Nic Lin's Blog

喜歡在地上滾的工程師

Devise使用Google實作登入

Step1: 申請 Google API

啟用”Web Fonts Developer API” and “Google+ API”

前往 https://console.developers.google.com 申請一個 Web Fonts Developer API

然後千萬注意要將 Google+ API 這個服務也開啟 不然在最後都成功送 key出去後 還會回傳一個 “Authentication failure! invalid_credentials” 錯誤喔!! 新增一個憑證: OAuth 2.0 用戶端 ID 專案 選擇:網路應用程式 以及在 已授權的重新導向 URI 填入回傳導向的 URL 如果暫時是用本機端的server的話,就要打: http://localhost:3000/users/auth/google_oauth2/callback

Step2: 安裝Gem及前置設定

gem 'settingslogic' #管理我們的秘密key
gem 'omniauth-google-oauth2'

bundle install

新增檔案:

class Settings < Settingslogic
  source "#{Rails.root}/config/application.yml"
  namespace Rails.env
end

前往 config/application.yml 填入剛剛申請的 Google api key! 包含了 用戶端ID以及用戶端密碼

新增檔案:

defaults: &defaults
  app_name: "demotest"
  google_oauth2_app_id: "自己申請的key"
  google_oauth2_secret: "自己申請的key"

development:
  <<: *defaults
  domain: "http:/localhost:3000" #最後 "/" 要拿掉

test:
  <<: *defaults

production:
  <<: *defaults

為了安全起見,我們必須把含有key的檔案加入gitignore,避免push的時候連帶key給別人。

/config/application.yml

Step3: Rails/controller && model設定

新增欄位 rails g migration AddColumnsToUsers provider:string uid:string name:string 記得跑`rake db:migrate’ 之後重開 rails server

然後前往 新增以下:

config.omniauth :google_oauth2, Settings.google_oauth2_app_id, Settings.google_oauth2_secret, {access_type: "offline",prompt: "select_account consent"}

寫 Callback method

rails g controller Users::OmniauthCallbacks

前往:

app/controllers/users/omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController   
    
  def google_oauth2
     
    @user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
 
    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
end

前往新增:


class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, :omniauth_providers => [:google_oauth2]
       
  def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
    data = access_token.info
    user = User.where(:provider => access_token.provider, :uid => access_token.uid ).first
    if user
      return user
    else
      registered_user = User.where(:email => access_token.info.email).first
      if registered_user
        return registered_user
      else
        user = User.create(name: data["name"],
          provider:access_token.provider,
          email: data["email"],
          uid: access_token.uid ,
          password: Devise.friendly_token[0,20]
        )
      end
    end
  end
  
end

Step4: Rails/routes && view設定

修改routes.rb,加入callback routes

devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }

在你view裡面加入google登入連結

<%= link_to "Sign in with Google", user_omniauth_authorize_path(:google_oauth2) %>

comments powered by Disqus