RailsアプリにAuth0をサクッと導入する


Auth0とは

Auth0は誰でも簡単に導入できる認証・認可プラットフォームです。

引用: Auth0 -公式-

Railsアプリであれば従来deviseなどのgemを使い認証機能を実装したり、omniauth-twitteromniauth-googleなどのgemでソーシャルログイン機能を実装していたと思います。
そんな機能をローコードで実現できるのがAuth0です。
(※ 間違いあればご指摘ください🪓)

こんなログイン画面がノーコードで実現できちゃいます😎
(※ ログイン画面自体のコーディングは必要ないけど、各種設定のために多少のコードは書きます。)

作業環境

MacBook Air (M1, 2020)
Ruby 3.0.2
Rails 6.1.4

前提条件

既にRailsアプリが存在しているものとします。
(認証・認可機能は未実装)

ちなみにAuth0実装前のルーティングはたったこれだけ。

config/routes.rb
Rails.application.routes.draw do
  root 'home#index'
  get 'dashboard', to: 'dashboard#show'
end

作業手順

1. Auth0アカウントを作成する

Auth0 公式HP にアクセスし、スクショの通りに進めます。

無事にアカウント作成できました✨

2. Rails に Auth0 を導入する

2-1. Auth0 でアプリケーションの作成

次は、先ほどのダッシュボードから作業します。

これでAuth0のアプリケーション作成は完了です✨

2-2. コールバックURL、ログアウトURLの設定

  • コールバックURLとは、Auth0がユーザーの認証後にリダイレクトする、あなたのアプリケーション内のURLです。
  • ログアウトURLとは、ユーザーが認可サーバーからログアウトした後に、Auth0が戻ることができるアプリケーション内のURLです。

引用: Auth0 -公式ドキュメント-

ここではAllowed Callback URLshttp://localhost:3000/auth/auth0/callbackAllowed Logout URLshttp://localhost:3000と設定しておきましょう。

2-3. Gemのインストール

お次はGemfileにomniauth-auth0omniauth-rails_csrf_protectionを追加します。

Gemfile
+ gem 'omniauth-auth0', '~> 3.0'
+ gem 'omniauth-rails_csrf_protection', '~> 1.0' # prevents forged authentication requests
terminal
% bundle install

2-4. Auth0設定ファイルの作成

Auth0の設定ファイルを作成します。
まずはconfigディレクトリにauth0.ymlという設定ファイルを作成します。

terminal
% touch config/auth0.yml

そして作成したファイルには下記のように記述します。

config/auth0.yml
development:
  auth0_domain: YOUR_DOMAIN
  auth0_client_id: YOUR_CLIENT_ID
  auth0_client_secret: <YOUR AUTH0 CLIENT SECRET>

※ ここに出てくるYOUR_DOMAIN, YOUR_CLIENT_ID, YOUR AUTH0 CLIENT SECRETは下記に記載してあります
※ ただし、このファイルはシークレットキーなどの秘匿情報が記載されているため、Git管理しないよう取扱い注意☝️

次にconfig/initializersディレクトリにauth0.rbという設定ファイルを作成します。
※ こちらはauth0.ymlじゃなくてauth0.rb、拡張子はrbなのでお間違い無く。

terminal
% touch config/initializers/auth0.rb

作成したファイルには下記のように記述します。

config/initializers/auth0.rb
AUTH0_CONFIG = Rails.application.config_for(:auth0)

Rails.application.config.middleware.use OmniAuth::Builder do
  provider(
    :auth0,
    AUTH0_CONFIG['auth0_client_id'],
    AUTH0_CONFIG['auth0_client_secret'],
    AUTH0_CONFIG['auth0_domain'],
    callback_path: '/auth/auth0/callback',
    authorize_params: {
      scope: 'openid profile'
    }
  )
end

2-5. Auth0用コントローラーの作成

次にAuth0用のコントローラーを作成します。
下記コマンドを実行しましょう。

terminal
% rails generate controller auth0 callback failure logout --skip-assets --skip-helper --skip-routes --skip-template-engine

そしてコントローラーの中身は下記のように編集します。

app/controllers/auth0_controller.rb
class Auth0Controller < ApplicationController
  def callback
    auth_info = request.env['omniauth.auth']
    session[:userinfo] = auth_info['extra']['raw_info']

    redirect_to '/dashboard'
  end

  def failure
    @error_msg = request.params['message']
  end

  def logout
    reset_session
    redirect_to logout_url
  end

  private

  AUTH0_CONFIG = Rails.application.config_for(:auth0)

  def logout_url
    request_params = {
      returnTo: root_url,
      client_id: AUTH0_CONFIG['auth0_client_id']
    }

    URI::HTTPS.build(host: AUTH0_CONFIG['auth0_domain'], path: '/v2/logout', query: to_query(request_params)).to_s
  end

  def to_query(hash)
    hash.map { |k, v| "#{k}=#{CGI.escape(v)}" unless v.nil? }.reject(&:nil?).join('&')
  end
end

次はルーティングの設定です。
下記の3つを追加します。

config/routes.rb
Rails.application.routes.draw do
   ...
+  get '/auth/auth0/callback' => 'auth0#callback'
+  get '/auth/failure' => 'auth0#failure'
+  get '/auth/logout' => 'auth0#logout'
end

2-6. セキュアモジュールの作成

次はセキュアモジュールを作成します。ここでいうセキュアモジュールとは、deviseでいうauthenticate_user!メソッドに当たります。つまるところログイン必須機能です。

app/controllers/concernsディレクトリにsecured.rbを作成します。

terminal
% touch app/controllers/concerns/secured.rb

中身は下記の通りにしてください。

app/controllers/concerns/secured.rb
module Secured
  extend ActiveSupport::Concern

  included do
    before_action :logged_in_using_omniauth?
  end

  def logged_in_using_omniauth?
    redirect_to '/' unless session[:userinfo].present?
  end
end

これでAuth0の導入は完了です🎉
お疲れ様でした!

3. Auth0 を配置

さて、ようやくAuth0を配置するフェーズに来ましたね😎
やるべきことはこれだけ。

  1. ログイン・ログアウトボタンの設置
  2. ログイン必須アクションにセキュアモジュールを導入
  3. ログイン後のビュー修正

では順を追って進めていきましょう。

3-1. ログイン・ログアウトボタンの設置

今回は単なる説明なので、どちらもホーム画面に設置します。

app/views/home/index.html.erb
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>

<%= button_to 'Login', 'auth/auth0', method: :post %>
<%= button_to 'Logout', 'auth/logout', method: :get %>

3-2. ログイン必須アクションにセキュアモジュールを導入

このアプリにはホーム画面とダッシュボードしか用意していません。
今回は仮に、ホーム画面はログインしていなくてもアクセスできるものとし、ダッシュボードはログインしていないとアクセスできないものとします。

なのでセキュアモジュールを導入するのはダッシュボード閲覧のコントローラー#アクションですね。
ダッシュボードではログインユーザーの情報を表示したいので、ログインユーザーデータを持ったインスタンス変数@userを定義しましょう。

app/controllers/dashboard_controller.rb
class DashboardController < ApplicationController
  include Secured # セキュアモジュールを導入

  def show
    @user = session[:userinfo]
  end
end

3-3. ログイン後のビュー修正

ここではシンプルにログインユーザーの名前を表示することにします。

app/views/dashboard/show.html.erb
<h1>Dashboard#show</h1>
<p>Find me in app/views/dashboard/show.html.erb</p>

<div>
  <p>User Profile: <%= @user['name'] %></p>
</div>

これで準備完了🙆‍♂️

4. Auth0 を実感

いよいよAuth0を実感する瞬間がやってまいりました!
http://localhost.3000にアクセスし、ログインボタンを押してください。
見事なまでのログイン画面が表示され、ログイン後はユーザー名が表示されるはずです✨

できた🎉

5. おわりに

いかがでしたか?
かなり簡単にAuth0を導入できたのではないでしょうか😊

このままでは肝心のRailsアプリケーションにユーザー情報を持っていなかったり、Google以外のソーシャルログインができなかったりと修正したい部分は多々ありますが、最低限の流れを掴んでいただけたら幸いです。

自分自身、Auth0を導入するのが今回初めてだったので、これからも気付きがあれば随時追記していこうと思います。