AWS Cognito を使って SSO 認証してみた

2024.07.31

46

こんにちは!原です!

今回は業務で AWS Cognito を使って SSO 認証(openid_connect)を実装しましたので、

備忘録的な感じで書き留めます。

前提:

AWS Cognito 側の設定はすでにされていたので、今回紹介はしません。

Ruby On Rails での実装になります。

devise gem は使いません。

dotenv-rails gem が入っている前提です。

SSO 認証、OpenID Connect を知っていること。

実装

OmniAuth gem のインストール

まず、Gemfile に以下の行を追加します。

gem 'omniauth'
gem 'omniauth-openid-connect'


その後、以下のコマンドを実行して gem をインストールします。

bash
bundle install

環境変数の設定

.envCLIENT_ID , CLIENT_SECRET を記載します。

COGNITO_DOMAIN= 'https://aaaa.com'
CLIENT_ID= 'xxxxx'
CLIENT_SECRET= 'yyyy'


COGNITO_DOMAIN: Cognito のドメイン

CLIENT_ID: Cognito のクライアント ID

CLIENT_SECRET: Cognito のクライアントシークレット

config の設定

次に、config/initializers/omniauth.rb に以下の設定を追加します。

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :openid_connect, {
    name: :cognito,
    scope: [:openid, :email, :profile],
    response_type: :code,
    discovery: true,
    client_options: {
      port: 443,
      scheme: 'https',
      host: ENV['COGNITO_DOMAIN'],
      identifier: ENV['CLIENT_ID'],
      secret: ENV['CLIENT_SECRET'],
      redirect_uri: 'http://localhost:3000/auth/cognito/callback'
    }
  }
end



redirect_uri: 認証後のリダイレクト先 (ローカル環境の場合: http://localhost:3000/auth/cognito/callback)

コントローラの設定

app/sesson_controller.rb を設定します。

class SessionsController < ApplicationController
  def create
    reset_session
    auth = request.env['omniauth.auth']
    user = User.find_or_create_by(uid: auth.uid, provider: auth.provider) do |u|
      u.email = auth.info.email
      u.name = auth.info.name
    end

    session[:user_id] = user.id
    redirect_to root_path, notice: 'Signed in!'
  end

  def destroy
    reset_session
    redirect_to root_path, notice: 'Signed out!'
  end

  def failure
    redirect_to root_path, alert: 'Authentication failed, please try again.'
  end
end

ルーティングの設定

ルーティングに OmniAuth のコールバック URL を追加するために、config/routes.rb を編集します。

Rails.application.routes.draw do
  get    '/auth/:provider/callback', to: 'sessions#create'
  get    '/auth/failure', to: 'sessions#failure'
  delete '/logout', to: 'sessions#destroy'

  root 'home#index'
end

User モデルの設定

ユーザー情報を保存するための User モデルを作成します。

rails generate model User provider:string uid:string name:string email:string
rails db:migrate

ビューの設定

ログインボタンやログアウトリンクをビューに追加します。

例えば、app/views/home/index.html.erb に以下のように記述します。

<% if session[:user_id] %>
  <p>Signed in as <%= current_user.name %></p>
  <%= link_to 'Sign out', logout_path, method: :delete %>
<% else %>
  <%= link_to 'Sign in with Cognito', '/auth/cognito' %>
<% end %>


current_user ヘルパーを追加するために、

app/controllers/application_controller.rb に以下のメソッドを追加します。

class ApplicationController < ActionController::Base
  helper_method :current_user

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
end

最後に

以上で、SSO認証(openid_connect) の実装が完了します。

簡単に認証が実装できていいですね!

この記事をシェアする