🙄

RailsでDicord認証でログインしてみる

2022/10/16に公開

はじめに

この記事ではOAuthを利用して、Discord認証を実装した時の備忘録です。
こちらの記事を参考にしたため、異なっている点のみ記載します。

各種バージョン

  • ruby 3.1.1p18
  • rails (7.0.4)
  • omniauth-discord (1.0.0)

1. gemのインストール

omniauth-discordを使うため、それぞれインストールします。

Gemfile
+ gem 'omniauth-discord'
+ gem 'omniauth-rails_csrf_protection'

2. ルーティングの設定

Google、Discord上のリダイレクトURIはそれぞれ下記を想定しています。

Provider URI
Discord http://localhost:3000/auth/discord/callback
routes.rb
Rails.application.routes.draw do
  root 'home#index'

  get 'auth/:provider/callback', to: 'sessions#create'
  get 'auth/failure', to: redirect('/')
  get 'log_out', to: 'sessions#destroy', as: 'log_out'

  resources :sessions, only: %i[create destroy]
end

$EDITOR=vim bin/rails credentials:edit -e developmentに以下の記述を追加します。

discord:
  client_id: クライアントID
  client_secret: クライアントシークレット

3. 設定ファイル

今回、登録しているメールアドレスを取得したいためscope: 'email'と記述しています。
scope: 'email'を記述しない場合、email: auth_hash.info.emailで取得した値はnilになってしまうので注意が必要です。

config/initializers/omniauth.rb
  provider :discord,
           Rails.application.credentials.discord[:client_id],
           Rails.application.credentials.discord[:client_secret],
           scope: 'email'

4. Model

今回は、OmniAuthから取得した情報の中から、name,email,image,uid,を取得します。
uidはProvide、ユーザーを識別するのに有効なってきます。
ユーザーをDBに登録する際、uidでProvider、ユーザーを識別することができます。

app/models/user.rb
def find_or_create_from_auth_hash(auth_hash)
   user_params = user_params_from_auth_hash(auth_hash)
   find_or_create_by(uid: user_params[:uid]) do |user|
      user.update(user_params)
   end
end

private

def user_params_from_auth_hash(auth_hash)
   {
      name: auth_hash.info.name,
      email: auth_hash.info.email,
      image: auth_hash.info.image,
      uid: auth_hash.uid,
   }
end

6. View

app/views/layouts/application.html.erb
<head>
   省略
</head>

<body>
  <header>
    <% if current_user %>
      <%= image_tag current_user.image %>
      <%= current_user.name %>さん
      <%= link_to "ログアウト", log_out_path %>
    <% else  %>
      ゲストさん
+     <%= button_to "Discordでログイン", "/auth/discord", method: :post, data: { turbo: false } %>
    <% end %>
  </header>
  <%= yield %>
</body>

ログインが成功すると、Discordの名前、画像が表示されます。

参考記事

Discussion