Open7

Gem Deviseを利用したGoogle認証を導入してみた(途中まで他の方の記事やってます)

いさみんいさみん

途中までの導入は以下の記事を参考にさせていただきました。
Googleログインの実装(devise + omniauth)

<開発環境>
macOS
VSCode
Rails 7.2.2.1
ruby-3.3.6
PostgreSQL 17.5

Gemのインストール

通常通りGemをインストール

omniauth用のカラムを追加

migrationファイルにいれる情報は少し異なりました。(2025/06/27時点)

 記載いただいてた内容
t.index ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true

dockerを使っているのでまた私と環境が違いますが、、、
g migration の後に
「AddIndexUidAndProviderToUsers」の場合:Userテーブルにカラムを追加
「CreateUsers」の場合:Userテーブル作成、t.xxxxxでカラムを入れている

ので、私は以下のように変えました。

自身で(bin/rails g migration AddIndexUidAndProviderToUsersに)記載した内容
class AddIndexUidAndProviderToUsers < ActiveRecord::Migration[8.0]
  def change
    add_index :users, ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true
  end
end


いさみんいさみん

ファイルへの記載
.env に環境変数を記載する(隠しファイル)

gem dotenv-railsを使用して記載。

routes.rb にルーティングの設定をする

Tailwindを使用していると、全ページのCSSを整える必要ありそうなので、
deviseの全ページビューファイルを、操作できるようにしました。
※認証だけなら特に気にする必要はないのですが、、、

  devise_for :users, controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
    passwords: 'users/passwords',
    confirmations: 'users/confirmations',
    unlocks: 'users/unlocks',
    omniauth_callbacks: 'users/omniauth_callbacks'
  }


  • omniauth_callbacks_controller.rb 記載をする
  • user.rb に記載する
  • registrations_controller.rb を記載する

そのままコピーさせていただきました。

いさみんいさみん

お?なんか「Sign in with GoogleOauth2」という文字が出てきた。
ひとまず記事をみてここまでやってました。

実際のDeviseのビューファイルには「<%= render "users/shared/links" %>」とあり、
部分テンプレート「users/shared/_links.html.erb」をみると以下のように記載あり。
※Deviseのコントローラーとビューファイルはコマンドで表示させる必要あり

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
  <% end %>
<% end %>

実際に「どこで」「何を」「このリンクを表示させる」というのをこのファイルでまとめて書いてあるって認識でいいのかな。

Deviseをちょっと理解できた気になれた。

…まだ続きます

いさみんいさみん

よし、早速Sign in with GoogleOath2でログインすんぞー……

_人人人人人人人人人人人人人人人人人人_
> このアプリのリクエストは無効です <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄

。゚(゚´ω`゚)゚。ピエンw

どうやら、Google APIコンソール上の認証情報 - APIとサービスにて
OAuth 2.0 クライアント IDの[承認済みのリダイレクト URI]に開発環境用のURLを新しく入れないといけないみたいです。

http://localhost:3000/users/auth/google_oauth2/callback

追加したところ、無事Google認証画面に移れました

いさみんいさみん

さて、Google認証でログインしよう。と思った矢先。

Google認証終わってログインできた!と思ったら
新規登録画面にページが飛んで、何と新規登録・ログインできず……

①userモデルのself.from_omniauthメソッドにデバッグコードを追加。

def self.from_omniauth(auth)
    # 以下1行[user = where ...]追加
    user = where(provider: auth.provider, uid: auth.uid).first_or_initialize

    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.name = auth.info.name
      user.email = auth.info.email
      user.password = Devise.friendly_token[0, 20]
    end

    # 以下[if文5行]と[return user]を追加
    # デバッグ:エラーが出た時にどのようなエラーが出るか確認。
    if user.save
      Rails.logger.debug "User saved: #{user.inspect}"
    else
      Rails.logger.debug "User save failed: #{user.errors.full_messages}"
    end

    return user
  end

こーすりゃ登録しようとした時に何のエラーが発生してるか出てくれる!!
…きっとGoogle上の認証となると「ローカルのメールアドレス、パスワードがないよー」って返ってきそう。

User save failed: ["Email can't be blank", "Password can't be blank"]
→Email,Passwordが空白だよ!!!

あっ……ハイ…w

いさみんいさみん

②userモデルのself.from_omniauthメソッド、デバッグコードを修正。
よく考えれば1行目はif文と同じことしていて、繰り返し文は処理した後の引数は消える
 →一旦1行目を消して「user =」を入れてみれば引数が消えないのかな?

以下で実施してみる。

def self.from_omniauth(auth)
    # 以下1行[user = where ...]コメントアウト
    # user = where(provider: auth.provider, uid: auth.uid).first_or_initialize
    
    # 以下の頭に[user = ]を追加
    user = where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.name = auth.info.name
      user.email = auth.info.email
      user.password = Devise.friendly_token[0, 20]
    end

    # デバッグ:エラーが出た時にどのようなエラーが出るか確認。
    if user.save
      Rails.logger.debug "User saved: #{user.inspect}"
    else
      Rails.logger.debug "User save failed: #{user.errors.full_messages}"
    end

    return user
  end

実施結果
→あれ?ログインできてる٩( ᐛ )وログイン、登録できちゃったよ???

あ。もしや引数userに直で入れ込んだから消えなくなった。
→ローカルで登録する時にuserの情報が消えてないから登録できるようになった。 ってことか。

…説明下手か?w
ひとまず解決してよかった〜

いさみんいさみん

よし、Renderにデプロイだー!
→デプロイが途中で止まり、一定時間経って、サーバが落ちちゃうΣ('◉⌓◉’)

あ。引数入れ忘れた。

.env に環境変数を記載する(隠しファイル)

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

その後も、Google認証を本番環境に入れるにはまた設定が必要らしく、
HOSTには実際に出している[https://]を抜いたサイトのURLを入れれば良いっぽい。

config/initializer/devise.rb
  config.omniauth :google_oauth2,
  ENV["GOOGLE_CLIENT_ID"],
  ENV["GOOGLE_CLIENT_SECRET"],
  {
    scope: "email,profile",
    redirect_uri: "#{ENV['HOST']}/users/auth/google_oauth2/callback"
  }
end

URLもconfig.hostsに入れる必要あり。

config/environments/production.rb
  # Only use :id for inspections in production.
  config.active_record.attributes_for_inspect = [ :id ]

  config.hosts << "saitamanear.com"