0. はじめに
お初にお目にかかります!!
toramaruJPです(`・ω・´)
昨日オリジナルアプリを作成しました!!
日頃からQiitaさんにはお世話になっているので、少しでも貢献できたらと思い、オリジナルアプリに導入したGithubログイン実装方法を記載したいと思います。
改善点等あった際には、ご指摘して下さると嬉しいです(´꒳`)
1. 実装概要
(1)Github連携の準備をしよう!(Github上)
(2)Github連携の準備をしよう!(実装上)
(3)Deviseを用いて、Githubログインを実装しよう!
2. 実装詳細
(1)Github連携の準備をしよう!(Github上)
まず、上記画像の右上の"Settings"タブを押します。 次に、左下の"Developer settings"タブを押します。 そうすると、上記画像のような画面になるので、右上の"New OAuth APP"を押します。 Localで動かす場合には、画像のように ・"Application name"には"アプリケーション名-development" ・"Homepage URL"には"http://localhost:3000/" ・"Authorization callback URL"には"http://localhost:3000/users/auth/github/callback" と記載します。最後に、"Register application"ボタンを押すと、完了です。
そうすると、"Client ID"と"Client Secret"が作成されます。
後ほど使うので、メモしておきましょう。
※ "Client ID"と"Client Secret"は、作成されたアプリケーション名をクリックした先の詳細に記載されてあるので、そこで確認できます。
(2)Github連携の準備をしよう!(実装上)
(a) アプリを立ち上げよう!
開発で使用するバージョンは以下の通りです。
Rails v5.1.6
ruby v2.3.1
下記コマンドで現在のバージョンを確認できます。
$ ruby -v
$ rails -v
rails newコマンドを使用してアプリの立ち上げを行います。
$ rails _5.1.6_ new oauth -d postgresql
下記のコマンド実行後、"http://localhost:3000/"
にアクセスをして、サーバーが立ち上がるか確認しましょう。
$ rails s
(b) OAuth認証に必要なGemをインストールしよう!
下記をGemfileに追記し、"bundle install"を行なってください。
省略
gem 'devise'
gem 'omniauth'
gem 'omniauth-github'
省略
$ bundle install
各ReadMe
・devise - https://github.com/plataformatec/devise
・omniauth - https://github.com/omniauth/omniauth
・omniauth-github - https://github.com/omniauth/omniauth-github
(c) Deviseの設定をしよう!
以下のコマンドを打ち、deviseに必要な設定ファイルを作成します。
$ rails g devise:install
これで、準備が整いました。
(3)Deviseを用いて、Githubログインを実装しよう!
(a) ユーザーテーブルを作成しよう!
$ rails g devise user
作成されたマイグレーションファイルを下記のように編集しましょう。
class DeviseCreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
## Database authenticatable
t.string :name, null: false, default: ""
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.string :provider, null: false, default: ""
t.string :uid, 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.inet :current_sign_in_ip
# t.inet :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, :name, unique: true
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
add_index :users, [:uid, :provider], unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
マイグレーションファイルを編集できたら
下記コマンドを実行してテーブルの作成を行います。
$ rails db:migrate
(b) users/registration_controllerを作成して、deviseのコントローラーを継承しよう!
下記のコマンドを実行します。
$ rails g controller users::registrations
作成されたファイルを、以下のように編集してください。
class Users::RegistrationsController < Devise::RegistrationsController
def build_resource(hash={})
hash[:uid] = User.create_unique_string
super
end
end
※ 上記"build_resource(hash={})"メソッドは、継承元の同メソッドをオーバーライドしています。具体的には、uidにランダムな値を代入しています。
下記において、継承元の同メソッドが確認できます。
https://github.com/plataformatec/devise/blob/bcdd54cc5ebd3413eeb3d17e3b634e8ace0d09f3/app/controllers/devise/registrations_controller.rb
(c) create_unique_stringメソッドを作成しよう!。
下記ファイルに、下記メソッドを追記してください。
def self.create_unique_string
SecureRandom.uuid
end
(d) ルーティングを追加しよう!
devise_for :users, controllers: {
registrations: "users/registrations"
}
(e) modelを編集しよう!
下記ファイルを、下記のように編集してください。
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:omniauthable, omniauth_providers: %i(github)
下記ファイルに、下記メソッドを追記してください。
def self.find_for_github_oauth(auth, signed_in_resource=nil)
user = User.find_by(provider: auth.provider, uid: auth.uid)
unless user
user = User.new(provider: auth.provider,
uid: auth.uid,
name: auth.info.name,
email: User.dummy_email(auth),
password: Devise.friendly_token[0, 20]
)
end
user.save
user
end
def self.dummy_email(auth)
"#{auth.uid}-#{auth.provider}@example.com"
end
現時点における該当modelは下記のようになります。
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:omniauthable, :confirmable, omniauth_providers: %i(google facebook github)
def self.create_unique_string
SecureRandom.uuid
end
def self.find_for_github_oauth(auth, signed_in_resource=nil)
user = User.find_by(provider: auth.provider, uid: auth.uid)
unless user
user = User.new(provider: auth.provider,
uid: auth.uid,
name: auth.info.name,
email: User.dummy_email(auth),
password: Devise.friendly_token[0, 20]
)
end
user.save
user
end
def self.dummy_email(auth)
"#{auth.uid}-#{auth.provider}@example.com"
end
(f) githubで取得したOAuth認証に必要な値("Client ID"と"Client Secret")を読み込む設定をしよう!
下記ファイルに、下記記述を追記してください。
Devise.setup do |config|
省略
config.omniauth :github, ENV["GITHUB_ID"], ENV["GITHUB_SECRET"], scope: 'user,public_repo'
省略
end
(g) .envファイルを作成しよう!
アプリケーションディレクトリ直下に下記ファイルを作成し、下記記述を追加してください。
GITHUB_ID=メモした"Client ID"
GITHUB_SECRET=メモした"Client Secret"
セキュリティ上、githubにプッシュさせない為、下記ファイルに下記記述を追記してください。
.env
.envに記載した環境変数を認識させる為に、"dotenv"というgemをインストールしてください。
gem 'dotenv-rails'
$ bundle install
(h) ログインボタンのリンクを設置するViewを作成しよう!
下記コマンドをターミナルで実行する。
$ rails g controller oauth_test index
作成されたViewファイルにログインボタンのリンクを設置します。
<p><%= notice %><%= alert %></p>
<% if user_signed_in? %>
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'githubでサインアップしてね', user_github_omniauth_authorize_path %>
<% end %>
ルーティングを再設定します。
devise_for :users, controllers: {
registrations: "users/registrations",
omniauth_callbacks: "users/omniauth_callbacks"
}
(i) コールバック処理のコントローラーを作成しよう!
下記ディレクトリに下記ファイルを作成し、下記を記述してください。
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def github
@user = User.find_for_github_oauth(request.env["omniauth.auth"], current_user)
if @user.persisted?
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
end
(j) コールバック先のルーティングを設定しよう!
下記ファイルに下記記述を追記します。
root :to => 'oauth_test#index'
(k) フラッシュメッセージを表示させよう!
下記ファイルに下記記述を追記します。
省略
<body>
<% if notice %>
<p class="alert alert-notice"><%= notice %></p>
<% end %>
<% if alert %>
<p class="alert alert-error"><%= alert %></p>
<% end %>
<%= yield %>
省略
以上になります!!!!!!
これで、"githubでサインアップしてね"リンクをクリックすれば、githubログイン認証してくれるはずです!!!!!
できなかったら( ゚д゚)( ゚д゚)
問題点を教えて頂けると嬉しいです(`・ω・´)
3. 最後に
初めて書きましたが、大変ですねこれ( ゚д゚)
書くのとまとめるのが大変( ゚д゚)
いっぱい書いてる人凄いな( ゚д゚)
ただ、自分の為にもなるのでこれからも書き続けます!!
最後まで見て頂いてありがとうございます!!