railsでソーシャルログインをしようとなると、ほぼ必ずといっていいほどお世話になるOmniAuth。本当にいいgemです。

ただ、最初にローカルで開発を進めるときにSNSのアカウントを作成して準備するのが面倒だったり、誰かに用意してもらわないいけなかったりして待ちが発生してしまうときがあります。

OmniAuthにはdeveloperというproviderが最初から用意されていて、これをSNSのダミーサービスとして使うことが可能です。

要はなんちゃってログインが可能になります。設定方法を以下にまとめていきます。

omniauth.rbに設定を追加

まず、config/omniauth.rbにdeveloperを使うことを以下のように明記します。

fieldsにはログイン画面に項目として設定するものを設定します(配列なので複数設定してOK)。

uid_fieldにはユーザーを一意に定めるために使う項目を指定します。場合のよってはemailとか、user_nameとかいろいろあるでしょう。

fieldsuid_fieldは利用予定があるSNSのソーシャルログインの仕様に合わせるとよいでしょう。本番さながらに動作確認をしやすい状態になります。

最後のcallback_pathはSNS側でログインが成功したあとのコールバックURLに相当するパスを意図的に変更したい場合に指定します。

これをなぜ設定しているかは後で説明します。

あと、この設定はローカルの開発環境のみにしたいので、unless Rails.env.production?として、本番環境などでは使えないようにしておきます。

そうしないと、万が一developerの入り口が見つかってしまったりすると不正ログインされてしまう可能性が高まってしまうでしょう。

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :developer,
           :fields => %i[uid],
           uid_field: :uid,
           callback_path: '/auth/developer/login' unless Rails.env.production?

  # 他にもいくつかprovider設定が書かれている
end

ルーティングの追加

あとは、config/routes.rbにdeveloper用のコールバックpathを設定しておきます。

Rails.application.routes.draw do
  # 略〜

  post 'auth/developer/login', to: 'sessions#developer_login'

  # 略〜
end

controlerの作成

今度はコントローラーです。上で設定したルーティングに合わせるなら、app/controllers/sessions_controller.rbというファイルを作ることになります。

以下のようにファイルを作成してみましょう。ここで、skip_before_action :verify_authenticity_tokenを追加しておきます。

そうしないと、developerの認証画面が表示されてログインボタンを押したときにActionController::InvalidAuthenticityTokenの例外が発生してCan't verify CSRF token authenticity.みたいなメッセージが表示されてしまいます。

class SessionsController < ApplicationController
  # これをしないと、ActionController::InvalidAuthenticityTokenとなってしまう
  skip_before_action :verify_authenticity_token, only: :developer_login

  def developer_login
    user_info = request.env['omniauth.auth']
    session[:user_info] = { uid: user_info['uid'] }

    # 認証成功後の処理を書く
    
    # お好きなURLへどうぞ
    redirect_to after_login_url
  end
end

viewファイルの修正

viewファイルはこんな感じ。念の為、if Rails.env.development?で表示制御を入れています。

また、rails 7かつHotWireを使っている場合はHotWireをここだけ向こうにしないと動作しないです。

data: { turbo: false }で無効にしておきましょう。

# 略〜

<% if Rails.env.development? %>
  <%= button_to '開発者としてログイン', '/auth/developer',
        method: :post,
        data: { turbo: false } %>
<% end %>

# 略〜

動作確認と設定内容についての補足

さて、ここまでやればあとは動作確認が可能です。上記のビューファイルが表示される画面からボタンを押して、以下のような画面が表示されたらOKです。

この認証画面はザルなので、好きな情報を入れて認証したことにできてしまいます。

developer providerとしてのログイン画面

このログインフォームはOmniAuthが自動で生成してくれているのですが、authenticity_tokenが付いていません(!)

そのため、ログインボタンを押すとActionController::InvalidAuthenticityTokenが発生して失敗します。

この例外発生を回避するために、先ほど紹介したコントローラーでskip_before_actionをしています。

ただ、これはdeveloper providerの都合であって他のSNSサービスにはskip_before_actionを適用したくはありません。

そこで最初のconfig/omniauth.rbに戻りますが、callback_pathを指定してdeveloper専用の口を作って対処しています。

developer providerがあると仕事が捗る

なんのこっちゃ?こんなの役に立つの?って思われるかもしれないですが、SNSの認証をテストしようとすると当然ながらSNSのアカウントを用意しないといけません。

場合によってはアカウントの種類や状況ごとに複数用意しないといけないこともあるでしょう。これが結構面倒で大変です。

最終的には本来のSNSアカウントを使ってテストをしないといけないですが、開発の初期はダミーログインできるととても仕事が捗ります。

アプリはとりあえずdeveloper providerを活用して作り込んでいって、ある程度形ができたら本来のSNSアカウントで動作確認、みたいな感じでスムーズに開発をすることができるでしょう。

この記事の環境情報

  • Ruby 3.1.2
  • rails 7.0.4
  • omniauth 2.1.0
  • おしるこが食べたい