无法在 Google 和玩具网站之间使用 Rails、Devise、Omniauth 上的 Ruby 设置简单的 OAuth2
Can't setup simple OAuth2 between Google and toy website using Ruby on Rails, Devise, Omniauth
我正在尝试通过构建一个小型 Web 应用程序在 Rails 上学习 Ruby。我的第一步是从 OAuth 登录开始,这样用户就可以使用 Facebook、Google 等登录。
但是当我转到本地主机上的 /users/sign_up
设计页面并单击使用 GoogleOauth2 登录时,它“什么都不做”并且控制台告诉我:
D, [2021-10-05T04:55:04.716439 #10144] DEBUG -- omniauth: (google_oauth2) Request phase initiated.
W, [2021-10-05T04:55:04.730086 #10144] WARN -- omniauth: Attack prevented by OmniAuth::AuthenticityTokenProtection
E, [2021-10-05T04:55:04.730681 #10144] ERROR -- omniauth: (google_oauth2) Authentication failure! authenticity_error: OmniAuth::AuthenticityError, Forbidden
我已经设置了 devise 和 omniauth-google-oauth2,并在 Google 开发人员控制台中注册了一个应用程序,将适当的回调 uris 添加为 http://127.0.0.1:3000/users/auth/google_oauth2/callback
和 http://localhost:3000/users/auth/google_oauth2/callback
,并使用 dotenv gem 将密钥和秘密写入 .env 以读取它们,运行 服务器 dotenv rails server
.
我想了解这里出了什么问题,为什么,我将如何调试它,以及如何修复它以便通过 Google 登录将我带到我的主页,“耶!你在 rails!"屏幕。
我的文件是这样设置的:
routes.rb:
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth' }
end
app/models/users.rb:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:timeoutable,
:omniauthable, omniauth_providers: [:google_oauth2]
def self.create_from_google_data(provider_data)
where(provider: provider_data.provider, uid: provider_data.uid).first_or_create do | user |
user.email = provider_data.info.email
user.password = Devise.friendly_token[0, 20]
user.skip_confirmation!
end
end
end
app/config/initializers/devise.rb:
...
config.omniauth :google_oauth2, ENV['GOOGLE_APP_ID'], ENV['GOOGLE_APP_SECRET'], scope: 'userinfo.email,userinfo.profile'
...
app/controllers/users/omniauth_controller.rb
class Users::OmniauthController < ApplicationController
def google_oauth2
@user = User.create_from_google_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Google') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Google. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def failure
flash[:error] = 'There was a problem signing you in. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
app/config/initializers/session_store.rb:
Rails.application.config.session_store :active_record_store, key: '_devise-omniauth_session'
如果需要任何进一步的说明来调试此问题,请告诉我。
对于遇到同样问题的任何人,我通过在项目中添加以下 gem 解决了这个问题,在尝试了我在网上找到的大量修复之后:
gem "omniauth-rails_csrf_protection"
为什么?没有明确的想法。非常欢迎提供更多解释的答案。
我正在尝试通过构建一个小型 Web 应用程序在 Rails 上学习 Ruby。我的第一步是从 OAuth 登录开始,这样用户就可以使用 Facebook、Google 等登录。
但是当我转到本地主机上的 /users/sign_up
设计页面并单击使用 GoogleOauth2 登录时,它“什么都不做”并且控制台告诉我:
D, [2021-10-05T04:55:04.716439 #10144] DEBUG -- omniauth: (google_oauth2) Request phase initiated.
W, [2021-10-05T04:55:04.730086 #10144] WARN -- omniauth: Attack prevented by OmniAuth::AuthenticityTokenProtection
E, [2021-10-05T04:55:04.730681 #10144] ERROR -- omniauth: (google_oauth2) Authentication failure! authenticity_error: OmniAuth::AuthenticityError, Forbidden
我已经设置了 devise 和 omniauth-google-oauth2,并在 Google 开发人员控制台中注册了一个应用程序,将适当的回调 uris 添加为 http://127.0.0.1:3000/users/auth/google_oauth2/callback
和 http://localhost:3000/users/auth/google_oauth2/callback
,并使用 dotenv gem 将密钥和秘密写入 .env 以读取它们,运行 服务器 dotenv rails server
.
我想了解这里出了什么问题,为什么,我将如何调试它,以及如何修复它以便通过 Google 登录将我带到我的主页,“耶!你在 rails!"屏幕。
我的文件是这样设置的:
routes.rb:
Rails.application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth' }
end
app/models/users.rb:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:timeoutable,
:omniauthable, omniauth_providers: [:google_oauth2]
def self.create_from_google_data(provider_data)
where(provider: provider_data.provider, uid: provider_data.uid).first_or_create do | user |
user.email = provider_data.info.email
user.password = Devise.friendly_token[0, 20]
user.skip_confirmation!
end
end
end
app/config/initializers/devise.rb:
...
config.omniauth :google_oauth2, ENV['GOOGLE_APP_ID'], ENV['GOOGLE_APP_SECRET'], scope: 'userinfo.email,userinfo.profile'
...
app/controllers/users/omniauth_controller.rb
class Users::OmniauthController < ApplicationController
def google_oauth2
@user = User.create_from_google_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Google') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Google. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def failure
flash[:error] = 'There was a problem signing you in. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
app/config/initializers/session_store.rb:
Rails.application.config.session_store :active_record_store, key: '_devise-omniauth_session'
如果需要任何进一步的说明来调试此问题,请告诉我。
对于遇到同样问题的任何人,我通过在项目中添加以下 gem 解决了这个问题,在尝试了我在网上找到的大量修复之后:
gem "omniauth-rails_csrf_protection"
为什么?没有明确的想法。非常欢迎提供更多解释的答案。