ruby-on-rails - Rails - Google oauth2 request.env['omniauth.auth'] 是 nil 使用具有多个模型的omniauth
问题描述
我正在开发一个 Rails 应用程序并使用omniauth google oauth2 gem设置 Google OAuth2 。有 2 个模型正在使用 devise 和 omniauth,并且按照本指南将 devise与多个模型一起使用(来自设计团队)不起作用。
目前,有 1 个现有模型devise
正在使用 facebook 的omniauth 策略。该模型的设置如下所示
devise :invitable, :database_authenticatable, :registerable,
:trackable, :validatable, :omniauthable, omniauth_providers: [:facebook, :facebook_access_token]
在一个单独的模型上,我想为谷歌添加一个omniauth策略(该模型也在使用devise
),它设置了标准设计
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
目前在devise.rb
那里为 facebook omniauth 设置
config.omniauth :facebook, ENV['facebook_app_id'], ENV['facebook_app_secret'], { scope: 'comma,seperated,fields', info_fields: 'comma,seperated,fields' }
并在omniauth.rb
那里为谷歌设置
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
{
scope: 'userinfo.email, userinfo.profile',
prompt: 'select_account',
image_aspect_ratio: 'square',
image_size: 50
}
end
在routes.rb
设计/omniauth 有多种路线
devise_for :users, path: 'users', controllers: {omniauth_callbacks: "users/omniauth_callbacks"} do
get 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
end
devise_for :admin_users, path: 'admin/admin_users'
注意 - controllers: {omniauth_callbacks: "admin/omniauth_callbacks"}
routes.rb 中没有 admin_users 因为我在启动服务器时收到此错误
Please add `devise :omniauthable` to the `AdminUser` model
如果omniauthable
将其添加到两个模型中,则在运行本地服务器时会出现此错误
Wrong OmniAuth configuration. If you are getting this exception, it means that either:
1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one
2) You are setting :omniauthable in more than one model
3) You changed your Devise routes/OmniAuth setting and haven't restarted your server
初始化文件和 routes.rb 中的当前设置允许服务器打开。因为我不能按照指南显示的方式使用它,所以我使用了 omniauth-google-oauth2 gem 指南中概述的1 次混合身份验证流程。在呈现该视图的页面中,我设置了这样的 javascript
<script src="https://apis.google.com/js/platform.js?onload=init"></script>
<script type="text/javascript">
function init() {
gapi.load('auth2', function() {
// Ready.
$('.google-login-button').click(function(e) {
e.preventDefault();
gapi.auth2.authorize({
client_id: "SOMEKEY.apps.googleusercontent.com",
cookie_policy: 'single_host_origin',
scope: 'email profile',
response_type: 'code'
}, function(response) {
if (response && !response.error) {
// google authentication succeed, now post data to server.
jQuery.ajax({type: 'POST', url: '/admin/admin-signin', data: response,
success: function(data) {
// response from server
console.log('********************')
console.log(data)
console.log('********************')
}
});
} else {
// google authentication failed
console.log('********************')
console.log(response)
console.log('********************')
}
});
});
});
};
init();
</script>
<div class="authform">
<a class="google-login-button">Sign in</a>
</div>
我已经像这样添加了这条路线
namespace :admin do
...
post '/admin-signin', to: 'application#google_oauth2'
end
目前,此设置允许我从谷歌呈现表单提示,我可以选择要使用的帐户。选择要使用的帐户后,我可以看到参数被发送到控制器操作,它看起来像这样
{"code"=>"4/LONGCODEOFSTRINGSANDNUMBERS",
"scope"=>"email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid",
"authuser"=>"1", "hd"=>"COMPANY", "session_state"=>"b0c030e5f1304f58695e19aa29cb73c942ac69b6..163d",
"prompt"=>"consent", "controller"=>"admin/application", "action"=>"google_oauth2"}
我处理此调用的控制器操作如下所示
def google_oauth2
@admin_user = AdminUser.from_omniauth(request.env['omniauth.auth'])
if @admin_user.persisted?
flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
sign_in_and_redirect @admin_user, event: :authentication
else
session['devise.google_data'] = request.env['omniauth.auth'].except(:extra)
redirect_to :back, alert: @admin_user.errors.full_messages.join("\n")
end
end
但问题是request.env['omniauth.auth']
nil 并且没有数据被发送。看起来我可能有几个选择
- 我需要做些什么
request.env['omniauth.auth']
才能出席吗?是否有一个回调我发送到其他地方到谷歌来取回request.env['omniauth.auth']
数据? - 实现
omniauthable
用户和管理员用户都可以使用的模型
有谁看到我做错了什么,或者可以添加什么?我想从 google oauth 得到的只是应该存在于request.env['omniauth.auth']
.
谢谢您的帮助
解决方案
这是一个非常专业和孤立的问题,可能对遇到此问题的其他人没有太大帮助。我在一个拥有各种谷歌密钥的组织内部制作了这个应用程序。所以对我来说这个问题的解决方案是使用正确的键。我之前使用的密钥不满足组织的设置,因此无法正常工作。一旦我为该组织使用了正确的密钥,它就可以正常工作。
推荐阅读
- r - T 检验错误 'arg' 必须为 NULL 或字符向量
- django - 如何在 UpdateAPIView django REST 中获取模型实例?
- javascript - 从 JSON 响应中删除不需要的标签
- angular - 从 StripeCheckout.configure Stripe Payment 与 Angular 10 集成获取电子邮件 ID
- xslt - XSLT 如何将常用标签包装在不同的包装元素中?
- python - PYTHON TCP SERVER 不能支持多个客户端请求
- c# - 如何将 Unity 组件连接到 Visual Studio Code?(带有统一组件的代码自动填充)
- python - (Python) 数据透视表 - 无法将数组数据从 dtype('float64) 转换为 dtype('
在制作数据透视表时,我遇到了转换数组数据错误的问题。我已经彻底检查了所有组件都是float64。但是错误仍然存在。我的代码片段转载如下:
bins_array=np.asarray(bins_list,dtype = np.float
- python - 如何在没有空单元格的情况下从工作表 A 复制到工作表 B?
- python - 关系不存在 Django Postgresql Dokku