omniatuh-facebookを用いたRailsにおけるFacebook認証
RailsにおいてFacebook認証を用いる場合omniauth-facebookを使うのが一つの手だ。
大体の流れとしては
- 認証urlをユーザに踏ませる
- facebookで認証してもらう
- 認証後自分のアプリの戻ってきてもらう
- 戻ってきてもらったときomniauth.authにユーザ情報が入ってるのでよしなに
だが開発中にデータベースをリセットした場合毎回毎回この手順を踏んでユーザを作成するのは面倒だし、ユーザに依存したデータを作成するときはもっと面倒。
この面倒な部分をFacebookのTest Userを使ってdb:seedすることで省略したい、というのが今回の試み
FacebookAppのTest User
FacebookAppには開発用にテストアカウントを作る仕組みがある。
これを用いると実ユーザを用いて開発するリスクを減らすことができる。
seedでTest Userを動的に作成してDBを初期化する
Userをomniauthから作るとする
seed.rb
test_users_client = Koala::Facebook::TestUsers.new(app_id: ENV['FACEBOOK_APP_ID'], secret: ENV['FACEBOOK_APP_SECRET'])
test_users_on_creation = test_users_client.create_network(10, true, 'email,user_birthday,user_friends,user_work_history,user_hometown,publish_stream')
graph = Koala::Facebook::API.new
test_users = graph.get_objects test_users_on_creation.map{|h| h['id']}
test_users_on_creation.each do |user_on_creation|
id = user_on_creation['id']
test_user = test_users[id]
h = OmniAuth::AuthHash.new
h.provider = 'facebook'
h.uid = id
h.info = OmniAuth::AuthHash.new(
test_user.slice('name', 'gender', 'first_name', 'last_name')
.merge(user_on_creation.slice('email'))
.merge({'image' => "http://graph.facebook.com/#{id}/picture"})
)
h.extra = OmniAuth::AuthHash.new
h.extra.raw_info = OmniAuth::AuthHash.new(test_user.merge({
'birthday' => "#{('01'..'12').to_a.sample}/#{('01'..'28').to_a.sample}/#{(1950..2010).to_a.sample}"
}))
User.create_with_omniauth(h)
end
大まかな流れは、
- koalaでTest Userを作る。この際Test Userを作るFacebookAppのidとsecretが必要
- create_network時に生成したTest Userの情報が返ってくる。permission(第三引数)は適当に
- ここでしか取れないtokenやemailなどが含まれているので保存する
- 3に含まれている情報は少ないので、更に情報を取得する。方法は通常ユーザと同様。
- 3,4からOmniauth::AuthHashを生成。
- 5を使用してよしなに
5でOmniauth::AuthHashを生成するのは、omniauthのomniauth.authと同じものを作りたかったから。
omniauthを使ってる場合omniauth.authを使ったアプリの作りになってる。。はず
自分のアプリで足りない情報はomniauth生成時に作成してもいいしUser作成時に突っ込んでもいい。
ここではbirthdayとimageを作成している。
birtydayに関しては完全にランダム値なのでFacebook側との情報の齟齬が発生する。