こんにちは、hachi8833です。引き続きDevise How-ToのOmniAuthシリーズをお送りします。
概要
- 原文: OmniAuth with multiple models
- リビジョン: 3 Mar · 8 revisions
読みやすさのため、横に長いコードを途中で改行しています。
原文の更新や誤りにお気づきの場合は、ぜひ@techrachoまでお知らせください。更新いたします。
OmniAuth: 概要(翻訳)
現時点では、DeviseのOmniauthableモジュールはそのままでは1つのモデルでしか利用できません。しかしご安心ください。OmniauthableはOmniAuthの単純なラッパーにすぎないので、方法はあります。
OmniAuthを複数モデルで認証に使えるようにするには、次の手順を進めます。
1. モデルから:omniauthable
引数を削除する
2. Deviseの設定ファイルからOmniAuthの設定を削除して新しいファイルに移動する
設定を切り出す前のdevise.rbが以下のようになっているとします。
Devise.setup do |config|
config.omniauth :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end
上を削除して、以下のように新しいomniauth.rbファイルに保存します。
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end
3. OmniAuth独自のルーティングを作成する
authentications_controller.rbというコントローラがある場合、次のようなルーティングを使います。
- Rails 3、Rails 4の場合
get "/auth/:action/callback", :to => "authentications",
:constraints => { :action => /twitter|google/ }
- Rails 5の場合
get "/auth/:action/callback", :controller => "authentications",
:constraints => { :action => /twitter|google/ }
OmniAuthによるすべての認証を同じcreate
アクションにルーティングしたい場合は、次のようにします。この方法はプロバイダの種類に依存しません。
get "/auth/:provider/callback" => "authentications#create"
マッピングエラーが発生する場合は、以下のようにルーティングをdevise_scope
でラップします。
devise_scope :user do
get "/auth/:provider/callback" => "authentications#create"
end
4. OmniAuthのon_failure
フックを設定する
この設定は、以下のようにOmniAuthの設定用ブロックの中で行えます。
Rails.application.config.middleware.use OmniAuth::Builder do
on_failure { |env| AuthenticationsController.action(:failure).call(env) }
end
あるいは、以下のように設定用ブロックの外でも行えます。
OmniAuth.config.on_failure = Proc.new { |env| AuthenticationsController.action(:failure).call(env) }
Deviseにはこの2番目のオプションが実装されていますが、omniauth.rbファイルが設定済みなので、1番目のオプションの方がシンプルに書けます。
この設定では、認証の失敗(ユーザーのログインのキャンセルなど)はすべてauthentications_controller.rb
コントローラのfailure
アクションにリダイレクトされます。
5. OmniAuthでの認証エラー処理
このライブラリのエラーは残念ながらあまり標準化されていないため、Devise自身で行っているエラー処理と同様に多くの条件分岐を処理するしかありません。ここから使えそうなコードをコピペして何とかすることになります。
RailsCastsの「Simple OmniAuth」も設定の参考になります。
関連記事(Devise)
OminiAuth
その他
- [Devise How-To]ユーザー登録ページへのルーティングをカスタマイズする(翻訳)
- [Devise How-To] sign_inとsign_outのデフォルトルーティングを変更する(翻訳)
- [Devise How-To]ユーザーのパスワードを自動生成する(シンプルな登録方法)(翻訳)
- Rails4: 古いdeviseのパスワードを新しいdeviseで使う方法
- Rails 3.1.0.rc8にしようとしたらdeviseが違うバージョンのbcryptに依存していてアップデートできない
- [Rails 3] deviseで使うモデルにfind_by_で始まる名前のscopeを定義するとrake db:migrate:resetが通らない
- [Rails 3] 失敗しないmigrationを書こう
- [Rails 3] Appサーバが複数だとdevise_openid_authenticatableで認証できない