「コタれん」にOAuth認証機能を追加してみた

OAuth認証を試したいと思い、コタれんOAuth認証機能を追加してみた。

コタれんでは既に devise による認証機能を持っていることを踏まえ、やりたいことは以下とする。

  • devise で既に登録されているユーザの emailアドレスと OAuth認証でログインした時の emailアドレスが一致すれば同一ユーザとして扱いたい

 devise 1.4.9 (あれ、古い?!)

Facebook にアプリを追加

  • 上記サイトでOAuth認証させたいアプリを追加する。
  • 後に「App ID/API Key」と「アプリのシークレットキー」を使うのでメモったりしとく。

ソースコードを修正

サーバ起動時にエラー

  • wikiに書かれている変更をひと通り実施し、ローカルでサーバを起動しようとするとエラーが発生。
    • oa-core gem が足りないらしい。
  • 対処
    • Gemfile に追加して bundle
gem 'oa-core'

ログインでエラー

  • Sign in with Facebook」のリンクをクリックして Facebook へリダイレクトされるはずがエラー発生。
  • heroku のログを見ると以下が出力されていた
Started GET "/users/auth/facebook" for 127.0.0.1 at 2012-06-22 00:52:03 +0900
NoMethodError (undefined method `info' for nil:NilClass):
  • 対処
    • config/initializers/omniauth.rb を追加し以下を追記。
  OmniAuth.config.logger = Logger.new(STDOUT)
  OmniAuth.logger.progname = "omniauth"

Facebookからのリダイレクト時にエラー

  • ユーザの検索でエラーになっているらしい
  • 対処
    • 既に登録されているユーザを email アドレスで判定したいため以下のように修正。
    • app/models/user.rb
  def self.find_for_facebook_oauth(auth, signed_in_resource = nil)                                                     
    user = User.find_by_email(auth.info.email)                                                                         
    unless user
      user = User.create(name:auth.extra.raw_info.name,                                                                
                         email:auth.info.email,
                         password:Devise.friendly_token[0,20]                                                          
                        )
    end
    user                                                                                                               
  end              

ログイン成功! Facebookに登録していある email と同じIDが既に存在すればそのユーザ情報でログインできるようになった。

本番環境にデプロイ時の注意事項

  • heroku にデプロイ時にFacebookに登録したアプリ情報の「App ID/API Key」と「アプリのシークレットキー」を環境変数として設定する必要がある。
$ heroku config:add FACEBOOK_APP_ID=xxxx --app kotaren
$ heroku config:add FACEBOOK_APP_SECRET=yyyy --app kotaren
  • あとはいつも通り push する。
$ git push heroku master

おまけ:アイコンのURLを取得する

  • ログインした後の曲一覧画面で、Facebookのユーザに紐付くアイコンを表示したくなったので認証時に Facebookから取得できる情報を調べてみた。
 provider: facebook
 uid: "xxxx"
 info: !map:OmniAuth::AuthHash::InfoHash
   nickname: xxxx
   email: xxxx
   name: xxxx
   first_name: xxxx
   last_name: xxxx
   image: http://graph.facebook.com/xxxx
   urls: !map:Hashie::Mash
     Facebook: http://www.facebook.com/xxxx
   verified: true
 credentials: !map:Hashie::Mash
   token: xxxx
   expires_at: xxxx
   expires: true
 extra: !map:Hashie::Mash
   raw_info: !map:Hashie::Mash
     id: "xxxx"
     name: xxxx
     first_name: xxxx
     last_name: xxxx
     link: http://www.facebook.com/xxxx
     username: xxxx
     gender: xxxx
     email: xxxx
     timezone: 9
     locale: ja_JP
     verified: true
     updated_time: xxxx
  • アイコンのURLは user.rb の self.find_for_facebook_oauth() にて「auth.info.image」で取得できることがわかる。後は user モデルにアイコンURL用のカラムを追加するなどして保持しておき、Viewに表示するようにする。


前にRuby勉強会でコタれんのレビューをしていただいてから、ずっとOAuth認証が気になっていたのでやっと実現できてよかった。次は twitter とかにもチャレンジしてみたいな。