Auth0をRails6に実装してみた

2022.01.24

Auth0でユーザ認証するアプリをはじめて作成してみました。ユーザ認証は開発中、運用中問わず注意して実装しないといけない機能ですが、Auth0を使うことで素早く、しかも安全なユーザ認証ができるという優れものです。しかも、Googleアカウントを使ったシングルサインオンなども対応も簡単にできますしね。

ということで試しに実装してみました。

用意するもの

  • Auth0 アカウント
  • Railsの開発環境

Railsの開発環境は自PCで動作できる環境(http://localhost:3000 へアクセスできる環境)があればOKです。

今回はRails6、Ruby 2.7で実装してみました。

Auth0にユーザ登録

まずは、こちらのリンクからAuth0へユーザ登録します。いつものメールアドレスの他に、GoogleやMicrosoftのアカウントでログインといったこともできます。

メールアドレスやパスワードを登録した後は、メールによる認証がある、といった流れも他Webサービスと同様ですね。

Auth0を組み込むための流れ

Auth0を組み込むために行う処理の流れをざっくり解説すると次の通りです。

  1. Auth0 Dashboardにてアプリケーションを登録
  2. (Railsプロジェクトを作成する)
  3. SDKをインストール
  4. Auth0の設定、初期化を追加する
  5. ログイン・ログアウトのControllerを追加
  6. ログイン・ログアウト時のViewを追加
  7. Routesの設定追加
  8. (必要に応じて)ユーザ情報の表示

ちなみに「ログイン・ログアウト時のViewを追加」では、よくある凝ったログイン画面を用意してません。ログイン画面へ遷移するためのボタン1個を配置するだけです。凝ったログイン画面はAuth0側で用意してくれます。

それに加えてログイン画面などの様々な設定の変更はすべてAuth0 Dashboard側でで可能でコードの編集は不要です。

公式チュートリアルあります!

今回はRails向けAuth0実装 公式チュートリアルに沿って実装してます。この解説もそれに沿ってますが、多少のアレンジがあります。あと、先のページからサンプルプロジェクトもダウンロードできますが、ブログのネタがなくなるのでイチからRailsアプリにAuth0を追加してます。

Auth0 Dashboardにてアプリケーションを登録

開発するアプリケーションをAuth0 Dashboardに登録します。メニューからApplications > Applicationsを選択し、Create Applicationします。ここでは"Rails6 TrainingApp"として登録しました。

Create Applicationでは、"Regular Web Applications"を選択します。

Auth0 Dashboardでパラメータ設定をする

先ほどの"Rails6 TrainingApp"のSettingに対して設定を追加します。ここではAuth0を動作させるための必要最小限の設定を行います。変更箇所は次の2箇所です。

項目
Allowed Callback URLs http://localhost:3000/auth/auth0/callback
Allowed Logout URLs http://localhost:3000

入力した後は、ページの最後にあるSave Changesボタンを押すのをわすれないようにしてください。

設定をわすれても大丈夫

開発中に、Allowed Callback URLsの設定を忘れてRailsアプリを実行したことがありました。

ログイン画面に遷移しても当然のことながら動作しませんが、その画面にはちゃんと解決方法が書いてありました。ので、動作しなくても画面には何かしらヒントが書かれているので、それを読んで落ち着いて対処すると動作するようになります。ご安心を。

SDKをインストールする

すでにRails6アプリが動作する環境ができているものとして進めていきます。まだ作成してない場合は、作成しておきましょう。

Auth0 SDKのインストールですがGemfileで扱えます。Gemfileの最後に以下の内容を追加します。

gem 'omniauth-auth0', '~> 3.0'
gem 'omniauth-rails_csrf_protection', '~> 1.0' # prevents forged authentication requests

で、ターミナルからインストールを実行します。

$ bundle install

Auth0の設定、初期化を追加する

設定ファイルと初期化を追加します。 config/auth0.ymlファイルを新規に作成して以下の内容を追加します。

# ./config/auth0.yml
development:
  auth0_domain: dev-abcabc.us.auth0.com
  auth0_client_id: abdefghabdefghabdefghabdefgh
  auth0_client_secret: nanikanosecretcodedesuyo

auth0_domain、auth0_client_id、auth0_client_secretはアプリごとに異なるので、先ほどの"Rails6 Training App"のAuth0 DashboardのBasic Informationに表示されているDomain、ClientID、Client Secretといった16進数の文字列をコピペします。

初期化処理として、先ほどの設定がSDKに渡されるようにします。こちらのコードは、そのままコピーでOKです。

# ./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

ログイン・ログアウトのController追加

ログイン成功、ログイン失敗、ログアウトといった処理をAuth0Controllerを新規作成して追記します。

# ./app/controllers/auth0_controller.rb
class Auth0Controller < ApplicationController

  #
  # ログイン成功
  #
  def callback
    # OmniAuth stores the informatin returned from Auth0 and the IdP in request.env[&#039;omniauth.auth&#039;].
    # In this code, you will pull the raw_info supplied from the id_token and assign it to the session.
    # Refer to https://github.com/auth0/omniauth-auth0#authentication-hash for complete information on &#039;omniauth.auth&#039; contents.
    auth_info = request.env[&#039;omniauth.auth&#039;]
    session[:userinfo] = auth_info[&#039;extra&#039;][&#039;raw_info&#039;]

    # Redirect to the URL you want after successful auth
    redirect_to &#039;/dashboard&#039;
  end

  #
  # ログイン失敗
  #
  def failure
    # Handles failed authentication -- Show a failure page (you can also handle with a redirect)
    @error_msg = request.params[&#039;message&#039;]
  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[&#039;auth0_client_id&#039;]
    }

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

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

ログインページへ飛ぶためのページを追加

ログイン、パスワードなどを入力するページはAuth0側で用意しているため、アプリ開発者はそのページへ飛ぶための処理を追加する必要があります。

といっても、することはボタンを1つ用意するだけです。

まず、top_controllerを用意します。

# ./app/controllers/top_controller.rb
class TopController < ApplicationController
end

Viewも用意します。

<!-- ./app/views/top/index.html.erb -->
<%= button_to 'Login', '/auth/auth0', method: :post %>

ログイン認証後のページを追加

ログイン認証後に表示するページを用意します。

ログイン認証が成功するとAuth0側から、さまざまな情報(ニックネーム、IDなど)がおくられます。なので、ニックネームを表示したり、IDを元にユーザ情報を自前のデータベースにて参照したりといったことが可能となります。

ここでは、ニックネームを表示させてみます。まずはdashboard_controllerから。

# ./app/controllers/dashboard_controller.rb
class DashboardController < ApplicationController
  include Secured

  def show
    # session[:userinfo] was saved earlier on Auth0Controller#callback
    @user = session[:userinfo]
  end
end

viewで@userに格納されているニックネームを表示させる処理となってます。@userには他にも様々な変数が格納されているので、いちど見てみるとよいでしょう。

<!-- ./app/views/dashboard/show.html.erb -->
<div>
  <p>Normalized User Profile:<%= @user["nickname"]%></p>
</div>

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

Routesの設定追加

最後にroutesを設定します。

# ./config/routes.rb
Rails.application.routes.draw do
  # ..
  root 'top#index'
  get '/auth/auth0/callback' => 'auth0#callback'
  get '/auth/failure' => 'auth0#failure'
  get '/auth/logout' => 'auth0#logout'
  get '/dashboard' => 'dashboard#show'
end

これで

これでAuth0のユーザ認証ができるRailsアプリができました。Railsに慣れている人であれば1時間もかからずに実装できるでしょう。

Auth0の情報は、本サイトに多数ありますので、そちらも参考にしてみてください!