はじめに
SNS認証の記事って結構ある割に、gemのバージョンが非対応だったり、APIの登録だったりで躓く所が多くて色々ハマるところが多かったので、無事動くように色々試しながら書いてみました。
初学者の僕が書いたので、初学者でも基本的にはコピペで実装できるようには書いてるつもりです。(説明はよく読んでください!)
ゴール
gooleアカウントでアカウント登録、ログインできるようになる。
前提
gem 'devise' 導入済み
$ rails generate devise:install # deviseの設定ファイル作成
$ rails generate devise user # Userモデル(usersテーブル作成)
$ rails generate devise:views users # usersのviewファイル作成
具体的にはここら辺はやってる前提で
STEP1 Google Cloud Platformに登録
登録が終わったら以下の手順で設定
↑↑↑入力必須欄以外は何もいじらずに進んでください!
次に認証情報を作成します(よく読んでね)
現地点ではlocalhost:3000
のやつだけで大丈夫です!
デプロイするときにオリジナル用の設定するの忘れないでください。
一応httpとhttpsどちらも作っておいてください
http://localhost:3000/users/auth/google_oauth2/callback
https://localhost:3000/users/auth/google_oauth2/callback
デプロイする時にこちらを入力してください
https://自分のアプリのURL/users/auth/google_oauth2/callback
※本番環境では必ずhttps
でURIを登録してください!
※https
ではなくhttp
で登録するとリダイレクトURIエラーが出ます。
発行されたクライアントIDとクライアントシークレットをどこかにメモっといてください。
以上でGoogle Cloud Platformの設定は終了です
見にくい写真ばかりで申し訳ないです
STEP2 いざ実装へ
2-1まずはgemを入れましょう!
※gem 'dotenv-rails'
は既に入れてる場合があるので入ってる人は飛ばして大丈夫です!
gem 'dotenv-rails'
gem 'omniauth', '1.9.1'
gem 'omniauth-google-oauth2'
※ gem 'omniauth'
は最新バージョンだとrailsとの相性が悪いそうなので、安定している gem 'omniauth', '1.9.1'
を入れてください。
これ知らんくて2時間ぐらい沼りました笑笑
$ bundle install
2-2 devise.rb追記
config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
特に張り付ける場所はどこでもいいですが270行目付近に関連したコメントアウトがあるのでそこら辺に上のコードをペーストしましょう。
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
2-3 .envと.gitignoreに記述
.envファイルに先ほど取得したクライアントIDとクライアントシークレットを追記します。
.envがないねんけど!!って人は
写真のように一番下の空間で右クリック
して.env
ファイルを作ってあげましょう!!
※作る階層ミスりがちなのでご注意
GOOGLE_CLIENT_ID=自分のクライアントID
GOOGLE_CLIENT_SECRET=自分のクライアントシークレット
続いて.gitignore
の一番下の行に.env
を記述してください!
~省略~
.env
2-4 routes.rbの編集
deviseのコントローラを編集するので変更が反映されるように書き換えます!
Rails.application.routes.draw do
# 変更前ここから
devise_for :users
# 変更前ここまで
# 変更後ここから
devise_for :users, controllers: {
omniauth_callbacks: "users/omniauth_callbacks"
}
# 変更後ここまで
resources :hoges
root 'hoges#index'
end
2-5 userモデルを編集
注意事項がいくつかあるのでコピペした後よく読んで下さい!!!
その1:コメントアウトのところにも書きましたが、:validatableの後ろに「,」コンマを忘れないこと
その2:**ユーザーマイページ
を作成している人、ユーザー情報にname
、profile
等のカラムがある人(要はdeviseのuserカラムに色々追加してる人)**は
user.追加してるカラム名 = auth.info.追加してるカラム名
を追記してあげてください!!
特別大サービスで
# user.name = auth.info.name
# user.profile = auth.info.profile
この2つはコメントアウトに書いておいたのでコメントアウトを外すだけでいいですよ!
※ユーザーマイページを作成している人は注意事項がもう一つあるので記事の最後まで読んで下さい!!
パスワード無しで更新する的なやつです。まぁ取り敢えず先に認証実装させましょう。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
#「validatable」の後ろにコンマ「,」をつけるのわすれずに↑↑
:omniauthable, omniauth_providers: %i[google_oauth2] # この一行を追加
# 追記部分ここから
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
# ※deviseのuserカラムに nameやprofile を追加している場合は下のコメントアウトを外して使用
# user.name = auth.info.name
# user.profile = auth.info.profile
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
#追記部分ここまで
end
2-6 マイグレーションファイル作成
認証を行う際にproviderカラム
と、uidカラム
を使用するのでマイグレーションファイルを作成します。
$ rails g migration AddOuthColumnToUsers provider:string uid:string
その後忘れずにrails db:migrate
しましょう。
$ rails db:migrate
2-6 コントローラー作成・編集
controllers/users/omniauth_callbacks_controller.rb
を以下の様に記述してください。
※そんなファイルないよ!って人は以下のコマンドを打って作ってください
$ rails g devise:controllers users
作成したら以下の通りに
# frozen_string_literal: true
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
# callback for google
def google_oauth2
callback_for(:google)
end
def callback_for(provider)
# 先ほどuser.rbで記述したメソッド(from_omniauth)をここで使っています
# 'request.env["omniauth.auth"]'この中にgoogoleアカウントから取得したメールアドレスや、名前と言ったデータが含まれています
@user = User.from_omniauth(request.env["omniauth.auth"])
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
end
def failure
redirect_to root_path
end
end
※一番上のマジックコメント# frozen_string_literal: true
も忘れずに入れてください!!
2-7 ラスト!登録ボタン作成
いよいよラストです。
サインインページのボタンを作成しましょう!
#変更前
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
<% end %>
<% end %>
#変更後
<%- if devise_mapping.omniauthable? %>
<%= button_to 'Sign in with Google', user_google_oauth2_omniauth_authorize_path %>
<% end %>
以上で認証の実装自体は終わりです。
STEP3 マイページ、ユーザー情報を更新する場合は必読
先ほど※ユーザーマイページを作成している人は注意事項がもう一つあるので記事の最後まで読んで下さい!!と書いたと思います。
ユーザー情報を更新する時、何をしないといけないですか??
そうです!現在のパスワードを入力しないといけません
ただ今回実装したGoogleアカウントで認証した場合、ランダムに自動生成されるようになってしまっています。
user.password = Devise.friendly_token[0,20]
これです。。。。
こちらを他のカラムの記述同様に書き直してもいいのですが、
流石に自分のgoogleアカウントのパスワードを晒すのは、、、、
って感じなので解決策として、、、、
パスワードなしでマイページを更新できるようにします!
手順はこの3つ
1. routes.rbの編集
2. registrations_controller.rbの編集
3. ユーザー編集画面の編集
3-1 routes.rbの編集
以下のように編集してください!
※users/omniauth_callbacks
の後ろに「,」つけるのお忘れなく!!!
# before
devise_for :users, controllers: {
omniauth_callbacks: "users/omniauth_callbacks"
}
#after
devise_for :users, controllers: {
omniauth_callbacks: "users/omniauth_callbacks" ,
registrations: "users/registrations"
}
3-2 registrations_controller.rbの編集
controllers/users/registrations_controller.rb
を開いてください。
40行目付近の#protected
のコメントアウト外して以下を追記してください。
# コメントアウト外す
protected
#追記
def update_resource(resource, params)
resource.update_without_password(params)
end
3-3 これでほんまのほんまにラスト ~パスワード更新関連の記述削除~
users/registrations/edit.html.erb
にて以下の記述を削除してください
# 以下の記述を削除
<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "new-password" %>
<% if @minimum_password_length %>
<br />
<em><%= @minimum_password_length %> characters minimum</em>
<% end %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "current-password" %>
</div>
サーバーを立ち上げて動作確認をしてください!
参考にさせていただいた記事
https://qiita.com/kakki0315/items/b1f0fd10432b273b7e90
https://qiita.com/akioneway94/items/35641ad30c2acb23b562
https://qiita.com/kizakey18/items/aed3c0830c67f19c65a0
https://qiita.com/d0ne1s/items/e1ee23ea23343d6aaa34
https://qiita.com/1992_momotaro/items/d8a220be528a7af69deb
先人の皆さまありがとうございました。
以上で終わりです。お疲れ様でした!何かエラー等あれば連絡してください!!