Rails實作第三方登入-Google

tingyiiii
tingyiiii
Published in
8 min readDec 15, 2020

凡走過必留下痕跡,邊複習邊想記錄使用這些套件的步驟及過程!

*使用的Ruby版本為2.6.6

  1. 第一步需要先去Google取得API
按上方的+建立憑證,選擇OAuth用戶端ID
選擇網頁應用程式
新增登入後重新導向的網址

按下建立後取得用戶端編號(Client ID)、用戶端密碼(Secret)

2. 確認專案使用的Devise套件使model中有加入omniauthable方法,另外也記得在後面加入允許哪些第三方(舉例這裡為Google)

# app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:# :confirmable, :lockable, :timeoutable, :trackable and :omniauthabledevise :database_authenticatable, :registerable,:recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:google_oauth2]end

更多方法一樣可以在devise套件的官方文件查看:

3. 安裝第三方登入需要的套件及設定環境變數的套件

在專案的Gemfile檔加入以下幾行:

gem 'omniauth'
gem 'omniauth-google-oauth2'
gem 'figaro'

存檔別忘了終端機執行

$ bundle install

figaro為設定環境變數的管理套件~在專端機執行:

$ bundle exec figaro install

會生成config/application.yml檔案,並將檔案加入.gitignore(不會加入版控)

4. 在剛剛figaro生成的 config/application.yml檔中加入Google的api ID及金鑰

google_client_id: "api_clientId"
google_client_secret: "api_secret"

5. 在專案的config/initializers/devise.rb檔中的加入以下,即設定好環境變數啦!

Devise.setup do |config|  .....  config.omniauth :google_oauth2, ENV['google_client_id'], ENV['google_client_secret']end

6. 在Devise使用的model(舉例這裡為User)加新欄位儲存第三方的 id

終端機下此指令新增新的migration檔(此寫法可自動幫忙寫好migration檔)

rails g migration add_omniauth_to_users provider:string uid:string

加完確認migration檔沒問題也別忘了在終端機執行:

$ rails db:migrate

7. 在Devise使用的model(舉例這裡為User)中建立類別方法:

class User < ApplicationRecord
...
# 找到user的話就登入,找不到就create新的user
def self.create_from_provider_data(provider_data)
where(email: provider_data.info.email).first_or_create do |user|
user.email = provider_data.info.email
user.password = Devise.friendly_token[0, 20]
user.name = provider_data.info.last_name
user.provider = provider_data.provider
user.uid = provider_data.uid
end
end
end

8. 在routes.rb檔中的devise後面加入omniauth的路徑及對應的controller:

Rails.application.routes.draw do# 加入新的路徑”users/omniauth_callbacks”
# 去找omniauth_callbacks_controller
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
root to: "home#index"end

Google Omniauth用戶端ID的重新導向URL就記得填入http://xxxxxxxx/users/omniauth_callbacks(xxxxxx為自己的網址,若為本機測試xxxx可填localhost:3000)

9. 最後一步就是在omniauth_callbacks_controller中加入第三方登入的方法~

之前如果沒有具現化過devise的controllers所以沒有omniauth_callbacks_controller檔的話可以在終端機下此指令:

$ rails generate devise:controllers users

之後就可找到app/controllers/omniauth_callbacks_controller.rb此檔案了!

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController  # 新增此段第三方登入的方法
def google_oauth2
@user = User.create_from_provider_data(request.env["omniauth.auth"])

if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect @user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
# 及這段第三方登入失敗的處理方法
def failure
redirect_to root_path
end
end

可以在網頁原本登入或註冊的畫面看到這個按鈕

(畫面完全沒美化還請多包涵><)

點進去後就會連到常見的使用Google登入畫面~點按帳號就可以登入原本的網站囉!大!功!告!成!啦 •́ ▾ •̀

以下最常見的錯誤畫面(我自己剛做的時候也是各種錯誤百出啊XD

這代表代入的client_id/secret有誤,記得回去檢查步驟4有沒有換成自己的api編號及密碼

--

--