LoginSignup
15
11

More than 1 year has passed since last update.

Rails Googleログインを実装する [SNS認証] 

Last updated at Posted at 2022-01-25

はじめに

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に登録

ここからアカウント登録してください!

登録が終わったら以下の手順で設定

以下写真です。見にくくて申し訳ないです。
1個目.png
2個目.png

3個目.png
4個目.png
5個目.png
6個目.png
7個目.png
8個目.png
9個目.png

↑↑↑入力必須欄以外は何もいじらずに進んでください!

次に認証情報を作成します(よく読んでね)

10個目.png

11個目.png
12個目.png
13個目.png
14個目.png

現地点ではlocalhost:3000のやつだけで大丈夫です!

デプロイするときにオリジナル用の設定するの忘れないでください。

一応httphttpsどちらも作っておいてください

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エラーが出ます。

15個目.png

発行されたクライアントIDとクライアントシークレットをどこかにメモっといてください。

以上でGoogle Cloud Platformの設定は終了です
見にくい写真ばかりで申し訳ないです:pray:

STEP2 いざ実装へ

2-1まずはgemを入れましょう!

gem 'dotenv-rails'は既に入れてる場合があるので入ってる人は飛ばして大丈夫です!

Gemfile

 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行目付近に関連したコメントアウトがあるのでそこら辺に上のコードをペーストしましょう。

config/initializers/devise.rb
# ==> 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ファイルを作ってあげましょう!!

※作る階層ミスりがちなのでご注意

ここ.png

.env

GOOGLE_CLIENT_ID=自分のクライアントID
GOOGLE_CLIENT_SECRET=自分のクライアントシークレット

続いて.gitignoreの一番下の行に.envを記述してください!

.gitignore

~省略~

.env

2-4 routes.rbの編集

deviseのコントローラを編集するので変更が反映されるように書き換えます!

routes.rb

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:**ユーザーマイページを作成している人、ユーザー情報にnameprofile等のカラムがある人(要はdeviseのuserカラムに色々追加してる人)**は

user.追加してるカラム名 = auth.info.追加してるカラム名
を追記してあげてください!!

特別大サービスで
# user.name = auth.info.name
# user.profile = auth.info.profile
この2つはコメントアウトに書いておいたのでコメントアウトを外すだけでいいですよ!

※ユーザーマイページを作成している人は注意事項がもう一つあるので記事の最後まで読んで下さい!!

パスワード無しで更新する的なやつです。まぁ取り敢えず先に認証実装させましょう。

user.rb

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

作成したら以下の通りに

controllers/users/omniauth_callbacks_controller.rb

# 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 ラスト!登録ボタン作成

いよいよラストです。
サインインページのボタンを作成しましょう!

views/users/shared/_links.html.erb

 #変更前
  <%- 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 マイページ、ユーザー情報を更新する場合は必読

先ほど※ユーザーマイページを作成している人は注意事項がもう一つあるので記事の最後まで読んで下さい!!と書いたと思います。

ユーザー情報を更新する時、何をしないといけないですか??

18個目.png

そうです!現在のパスワードを入力しないといけません

ただ今回実装したGoogleアカウントで認証した場合、ランダムに自動生成されるようになってしまっています。

user.rb
 user.password = Devise.friendly_token[0,20]

これです。。。。

こちらを他のカラムの記述同様に書き直してもいいのですが、
流石に自分のgoogleアカウントのパスワードを晒すのは、、、、
って感じなので解決策として、、、、

パスワードなしでマイページを更新できるようにします!

基本的にこの記事で実装できますが、混乱する点が多いので解説します!!

手順はこの3つ

1. routes.rbの編集
2. registrations_controller.rbの編集
3. ユーザー編集画面の編集

3-1 routes.rbの編集

以下のように編集してください!

users/omniauth_callbacksの後ろに「,」つけるのお忘れなく!!!

routes.rb
  # 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のコメントアウト外して以下を追記してください。

controllers/users/registrations_controller.rb

 # コメントアウト外す
  protected

  #追記
  def update_resource(resource, params)
    resource.update_without_password(params)
  end

3-3 これでほんまのほんまにラスト ~パスワード更新関連の記述削除~

users/registrations/edit.html.erbにて以下の記述を削除してください

views/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
先人の皆さまありがとうございました。

以上で終わりです。お疲れ様でした!何かエラー等あれば連絡してください!!

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11