今回は、GitHubのOAuthを試してみたときのメモです。
実装環境
それではGitHubのOAuthを実装していきましょう。
(i) Deviseと関連gemのインストール
gem 'devise' gem 'omniauth' gem 'omniauth-github'bundle してインストールします。
(ii) Deviseの設定とUserモデルを作成
メールの受信には letter_opner_webというgemを使っていきます。READMEを参考に設定します。
参考記事
DeviseのREADME.mdを参考にDeviseの初期設定をして、Userモデルを作成します。
$rails g devise User
今回は、メールアドレスで登録したユーザーには登録したアカウント有効化メールを送りたいのでConfirmableのコメントを有効化します。 migrationファイルはこんな感じです。
class DeviseCreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable # t.integer :sign_in_count, default: 0, null: false # t.datetime :current_sign_in_at # t.datetime :last_sign_in_at # t.string :current_sign_in_ip # t.string :last_sign_in_ip ## Confirmable t.string :confirmation_token t.datetime :confirmed_at t.datetime :confirmation_sent_at t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end end
(iii) このリンクに飛んで、APIの設定をしていきます。
Application nameにはアプリケーション名、今回はローカルで試したいのでHomepage URLには「http://localhost:3000.com」、Deviseとその他もろもろを使っていきたいので、Callbackに「http://localhost:3000/users/auth/github/callback」とします。
[注意] Client IDとClient Secretは外部にもれないようにしましょう。
(iv) Deviseのwikiを参考にログイン・登録を実装
参考記事 OmniAuth: Overview · plataformatec/devise Wiki · GitHub
上記のDeviseのwikiにサンプルコードがあったので、これを参考に実装していきます。
group :development, :test do gem 'dotenv-rails' end
bundle してインストールします。
- .envファイルを作成して、Client IDとClient Secretの環境変数を設定していきます。
CLIENT_ID=◯◯◯◯◯◯◯ CLIENT_SECRET=◯◯◯◯◯◯◯
gitで管理している場合はgitignoreを設定して外部にClient IDとClient Secretが漏れないようにしましょう.
- providerとuidを格納するためのカラムをusersテーブルに追加します。
$rails g migration AddOmniauthToUsers provider:string uid:string $rails db:migrate
- 参考記事を元にDeviseにGitHubの設定をしていきます。
config.omniauth :github, ENV['CLIENT_ID'], ENV['CLIENT_SECRET'],scope: "user,repo,gist"
scopeにユーザーからとってきたい情報を指定することができます。今回はomniauth-githubのREADME通りにuserとrepoとgistを指定します。 その他にもscopeに指定できるみたいですね。
次にuserモデルにマウントの処理を書きます。
devise :omniauthable, omniauth_providers: %i[github]
そしてログインリンクを設置していきます。
<%= link_to "GitHubでログイン/登録する", user_github_omniauth_authorize_path %>
このリンクからコールバック(同意画面的なやつ) に進むことが出来ます。
- ログイン登録機能の実装
DeviseにOmniauthCallbacksControllerがあるので、これを継承したコントローラーを作成してログイン・登録機能を実装します。
devise/omniauth_callbacks_controller.rb at master · plataformatec/devise · GitHub
$rails g controller users::omniauth_callbacks
デフォルトではApplicationControllerを継承していますが、omniauth_callbacks_controllerに書き換えましょう!! そして記事を参考に実装します。
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def github @user = User.from_omniauth(request.env['omniauth.auth']) #ここの処理をuserモデルで実装 if @user.present? sign_in_and_redirect @user, event: :authentication> set_flash_message(:notice, :success, kind: "Github") if is_navigational_format? else session["devise.github_data"] = request.env["omniauth.auth"] redirect_to new_user_registration_url end end def failure redirect_to root_path end end
githubアクションで、ユーザーが存在すればログインしてrootページにリダイレクトする処理を書いています。 3行目のfrom_omniauthというクラスメソッドでユーザーのアカウントがなければアカウントを作成し、あればスルーする という処理を書きます。コードは以下の通りです。
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable,:confirmable ,:omniauthable, omniauth_providers: %i[github] # ここでユーザーのアカウントがなければアカウントを作成し、あればスルーする def self.from_omniauth(auth) where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.email = auth.info.email user.password = Devise.friendly_token[0,20] user.skip_confirmation! end end end
以上でGitHubの登録・ログイン機能が実装できました