【问题标题】:Cannot get rails OmniAuth for Google work with devise无法让 Rails OmniAuth for Google 与设计一起使用
【发布时间】:2018-01-21 10:47:53
【问题描述】:

我正在使用“omniauth-google-oauth2”gem 来设置谷歌登录以及设计登录。还在教程中提到的应用程序根目录中添加了一个 ssl (File => cacert.pem)

/config/initializers/omniauth.rb

OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do  
provider :google_oauth2,"google_clent_id", "google_secret_id",{client_options: {ssl: {ca_file:Rails.root.join("cacert.pem").to_s}}} 
end

/config/initializers/devise.rb

  config.omniauth :google_oauth2, "google_client_id", "google_secret_id", { name: 'google' }

routes.rb

devise_for :users, :controllers => { sessions: "sessions", registrations: 'registrations',:omniauth_callbacks => "users/omniauth_callbacks" }
  get 'auth/:provider/callback', to: 'sessions#create'
  get 'auth/failure', to: redirect('/')
  get 'signout', to: 'sessions#destroy', as: 'signout'

controllers/users/omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
skip_before_action :verify_authenticity_token
  def google_oauth2
      @user = User.from_omniauth(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
end

user.rb

devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :omniauthable,
         :omniauth_providers => [:google_oauth2]
    def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      full_name = auth.info.name.split(" ")
      user.first_name = full_name[0]
      user.last_name = full_name[1]
      user.email = auth.info.email
      user.oauth_token = auth.credentials.token
      user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save!
    end
  end

sessions_controller.rb

  def create
    user = User.from_omniauth(env["omniauth.auth"])
    session[:user_id] = user.id
    redirect_to root_path
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_path
  end

在我看来(html.erb 文件)

<% if current_user %>
        Signed in as <strong><%= current_user.name %></strong>!
        <%= link_to "Sign out", signout_path, id: "sign_out" %>
      <% else %>
        <%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path, id: "sign_in" %>
      <% end %>

当我点击登录链接时,我被重定向到谷歌帐户选择/登录页面。当我使用帐户登录时,页面被重定向到根路径,但用户尚未登录。 但是用户详细信息已记录到数据库用户表中。 服务器日志如下所示,

Started GET "/users/auth/google_oauth2" for 127.0.0.1 at 2018-01-21 15:49:11 +0530
   (0.3ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
(google_oauth2) Request phase initiated.
Started GET "/users/auth/google_oauth2/callback?state=*****&code=4/****" for 127.0.0.1 at 2018-01-21 15:49:16 +0530
(google_oauth2) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#google_oauth2 as HTML
  Parameters: {"state"=>"****", "code"=>"4/****"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."provider" = ? AND "users"."uid" = ? ORDER BY "users"."id" ASC LIMIT ?  [["provider", "google_oauth2"], ["uid", "*****"], ["LIMIT", 1]]
   (0.1ms)  begin transaction
  SQL (3.5ms)  UPDATE "users" SET "oauth_token" = ?, "oauth_expires_at" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["oauth_token", "*********"], ["oauth_expires_at", "2018-01-21 11:19:16"], ["updated_at", "2018-01-21 10:19:17.882842"], ["id", 2]]
   (105.7ms)  commit transaction
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 2], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Completed 302 Found in 220ms (ActiveRecord: 111.1ms)


Started GET "/" for 127.0.0.1 at 2018-01-21 15:49:18 +0530
Processing by HomeController#index as HTML
  Rendering home/index.html.erb within layouts/application
  Rendered layouts/sliders/_slider_home.html.erb (0.4ms)
  Rendered customers/_index.html.erb (1.6ms)
  Rendered home/index.html.erb within layouts/application (3.4ms)
  Rendered layouts/header/_style_files.html.erb (0.3ms)
  Rendered layouts/_meta_files.html.erb (1.5ms)
  Rendered layouts/logos/_logo_main.html.erb (1.4ms)
  Rendered layouts/header/_header_search.html.erb (2.5ms)
  Rendered layouts/header/_header_navigation.html.erb (0.6ms)
  Rendered layouts/logos/_logo_secondary.html.erb (1.1ms)
  Rendered layouts/footer/_footer.html.erb (2.3ms)
  Rendered layouts/static/_hover_top.html.erb (0.4ms)
  Rendered layouts/footer/_script_files.html.erb (1.1ms)
Completed 200 OK in 727ms (Views: 724.5ms | ActiveRecord: 0.0ms)

出于安全原因,某些字段已更改为星号(****)。 用户信息被保存到数据库中的“用户”表中,甚至不需要任何权限。但是为什么用户没有登录呢? 我的常规设计登录表单也不起作用。请帮助我理解我在这里做错了什么? 提前致谢。

【问题讨论】:

  • 我可以知道创建一个新的会话控制器而不是使用设备的会话控制器的原因吗?
  • @AakashGupta 用于omniauth。

标签: ruby-on-rails devise omniauth omniauth-google-oauth2


【解决方案1】:

如果有人落后,对我来说问题是我的 gemfile 中缺少 1.9.1。添加它为我解决了这个问题。我花了几个小时检查我的代码是否有错别字,但它一直都是宝石。

gem "omniauth", "~> 1.9.1" 宝石“omniauth-google-oauth2”

【讨论】:

    【解决方案2】:

    您的代码看起来不错。但我认为在routes.rb 你应该添加回调作为附加参数

    devise_for :users, controllers: { 
    omniauth_callbacks: 'users/omniauth_callbacks' 
    }
    

    并绑定或创建用户

    def self.from_omniauth(access_token) 
    data = access_token.info 
    user = User.where(email: data['email']).first 
    # Uncomment the section below if you want users to be created if they don't exist 
    # unless user 
    # user = User.create(name: data['name'], # email: data['email'],
     # password: Devise.friendly_token[0,20] # ) 
    # end 
    user 
    end
    

    不要在

    中使用此配置
    config/initializers/omniauth.rb:
    
    Rails.application.config.middleware.use 
    OmniAuth::Builder do 
    provider :google_oauth2, 
      ENV['GOOGLE_CLIENT_ID'],
      ENV['GOOGLE_CLIENT_SECRET'] 
    end
    

    在中定义您的应用程序 ID 和密码

    config/initializers/devise.rb
    

    您可以使用其他权限

    Rails.application.config.middleware.use
     OmniAuth::Builder do 
    provider :google_oauth2, 
    ENV['GOOGLE_CLIENT_ID'], 
    ENV['GOOGLE_CLIENT_SECRET'],
     { 
    name: 'google', 
    scope: 'email, profile, plus.me, http://gdata.youtube.com', 
    prompt: 'select_account',
     image_aspect_ratio: 'square', 
    image_size: 50
     }
    

    结束

    如果你改变

    config.omniauth :google_oauth2, 
    ENV["GOOGLE_ID"],
    ENV["GOOGLE_SECRET"]
    

    服务器甚至不会启动。 然而,问题似乎出在传递给 this 的参数中

    config.omniauth :google_oauth2, ENV["GOOGLE_ID"], ENV["GOOGLE_SECRET"],
        { :name => "google", # this is the line that was giving me trouble
        :scope => "email",
        :prompt => "select_account",
        :image_aspect_ratio => "square",
        :image_size => 50 }
    

    我认为您正在更改返回身份验证的方式 即

    :google => {:name => "foo", :email => "bar@email.com" }
    

    改变然后不匹配的路线。生成的设计

    user_google_oauth2_omniauth_authentication_path
    

    仍然指向

    users/auth/google_oauth2/authentication
    

    但是参数中的标记线使oauth期望

    users/auth/google/authentication
    

    【讨论】:

    • 在尝试了这个解决方案之后,我又遇到了一个错误。单击登录链接时重定向到显示“未找到。身份验证通道。”的页面。
    • 您目前遇到什么错误?我认为代码应该可以工作。它对我有用。
    • 当我点击登录链接时,我被重定向到一个页面,该页面显示 Not found。身份验证通路 .
    • devise_for :users, path: "auth", :controllers => {sessions: 'sessions', registrations: 'registrations', omniauth_callbacks: 'omniauth_callbacks'}
    • 重新检查您的路线匹配。我已在解决方案中添加了该方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    相关资源
    最近更新 更多