Help us understand the problem. What is going on with this article?

【Rails】omniauth_callbacks_controllerについて

はじめに

facebookのログイン機能の実装をしていて、難しいなと思った場所の操作をできるだけわかりやすく書こうと思います。一通りの流れが書いてある記事はたくさんありますが、この一つの操作だけに絞ることは本来はMVCモデルとしてはあまりわかりやすいものではないです、しかし詳しく書くためにあえてomniauth_callbacks_controllerのことだけに留めます。

omniauth_callbacks_controllerとは

omniauth_callbacks_controllerは主にdeviseの:omniauthableを使う時に使うコントローラーです。
facebookなどが提供しているリソースサーバーからの応答をコールバック として受け取り、どういう処理をするかを書くファイルです。

rails g devise:controllers Model

上記のコマンドを実行すると下記のファイルが生成されます。

app/controllers/users/confirmations_controller.rb
app/controllers/users/omniauth_callbacks_controller.rb
app/controllers/users/passwords_controller.rb
app/controllers/users/registrations_controller.rb
app/controllers/users/sessions_controller.rb
app/controllers/users/unlocks_controller.rb

この二番目のcontrollerのことです。

実際にみてみる

omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def facebook
    callback_for(:facebook)
  end

  def callback_for(provider)
    @user = User.from_omniauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, event: :authentication
      set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
    else
      session["devise.#{provider}_data"] = request.env["omniauth.auth"].except("extra")
      redirect_to new_user_registration_url
    end
  end

  def failure
    redirect_to root_path
  end
end

まず最初にfacebookのクラスメソッドが呼び出され、その中でcallback_forメソッドを指定し、引数として:facebookを指定しています。呼び出されたcallback_forメソッドで最初に@userにリソースサーバーから送られてきた情報全てを代入します。そしてその@userが保存してあった場合は指定したリンクにredirectをし、ログインが成功しましたというようなアラートを出します。
もし、
既に保存していなかった場合はsessionにデータを保持し、新規登録の画面へとredirectします。
そしてもしもcallbackが失敗した場合はroot_pathへredirectします。

このコードを理解するために以下にコードの前提知識を記しておきます。

前提知識

コード 意味
provider 今回でいうfacebookのことです、どこから提供されたものなのかということを指します、しかし引数として使われているので別に名前は何でも良いです
:facebook devise.rbに設定しているfacebookの設定のことです
request.env["omniauth.auth"] リソースサーバーからOmniAuthで取得したすべての情報をrequest.env["omniauth.auth"]というハッシュとして受け取ったものです
.from_omniauth user.rbに設定しているメソッドのことです。このメソッドではrequest.env["omniauth.auth"]で受け取った情報をDBに保存したり、何も登録してないときは新しいインスタンスを作成するというような操作を行っているメソッドです
.persisted? オブジェクトが新しいレコードでない、かつオブジェクトが削除されていない時に,Trueを返すメソッドです
sign_in_and_redirect サインインをしたのちに、保存された場所にリダイレクトしてから、after_sign_in_path_forで指定されたURLにリダイレクトしようとするものです
set_flash_message flashメッセージを出すメソッドです
is_navigational_format? フラッシュメッセージを発行する必要があるかどうかを確認するものです
.capitalize 先頭以外のアルファベットはすべて小文字にし、先頭のアルファベットのみを大文字にして出力するメソッドです
.except 指定した条件を外すメソッド
failure 失敗した場合という意味

参考記事

https://rubydoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers
https://qiita.com/ShinyaKato/items/a098a741a142616a753e
https://techracho.bpsinc.jp/hachi8833/2017_05_16/40096
http://casa-jpn.hatenablog.com/entry/2018/05/06/221105
https://github.com/plataformatec/devise#controller-filters-and-helpers

最後に

いかがだったでしょうか、oauthの機能はomniauth_callbacks_controllerのみで完結するものではないのでここだけを理解したとしても全てを理解したことにはなりませんし、まだ全体的な流れは掴めないかと思います。しかし、全体的に流れがわかって実際にどのように操作をするかがわかるとさらに理解が進みますし、deviseについての理解も深まったのではないでしょうか。
一つでもやくに立てる情報がありましたら嬉しいです。
また、なれないqiita投稿ですので間違っている点がありましたら指摘をよろしくお願いします。

yoshi_4
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away