Rails / Google SSO - 身份验证弹出窗口导致:阻止了具有来源的框架
Rails / Google SSO - auth popup causing: Blocked a frame with origin
我有一个 Rails 应用程序,它使用 Google SSO 来登录/注册用户。它在 Safari 中运行良好,但在 Chrome 中我不断收到此错误:
Blocked a frame with origin "[domain]" from accessing a frame with origin "https://accounts.google.com". Protocols, domains, and ports must match.
我之前用这个"solution"解决过:https://github.com/zquestz/omniauth-google-oauth2/issues/122#issuecomment-60510241
但我最近注意到它突然停止使用上述解决方案来代替 Safari。
我当前的实现如下所示(咖啡脚本):
$(document).ready ->
$.ajax
url: 'https://apis.google.com/js/client:plus.js?onload=gpAsyncInit'
dataType: 'script'
cache: false
window.gpAsyncInit = ->
$('.googleplus-login').click (e) ->
e.preventDefault()
gapi.auth.authorize {
immediate: false
response_type: 'code'
cookie_policy: 'single_host_origin'
client_id: '[id]'
scope: 'email profile'
}, (response) ->
if response and !response.error
# google authentication succeed, now post data to server and handle data securely
jQuery.ajax
type: 'POST'
url: '/auth/google_oauth2/callback'
dataType: 'json'
data: response
success: (json) ->
# response from server
[this doesn't happen]
return
else
# google authentication failed
我在 Google 的文档中没有看到任何地方描述这个错误,所以我不太确定如何修复它。
我确定我有相同的协议 https
,所以它一定是别的东西。我猜是域名。
我看到其他网站(如 Stack-overflow)使用不同的流程,其中不显示弹出窗口,而是将用户重定向到另一个页面。想知道这是否可以作为解决方案(和/或)推荐的方法来避免我的错误。
在那种情况下,我可以在 Google 的文档丛林中的何处找到相关文档?
更新
这是我的控制器代码的相关部分。
def google_authentication
respond_to do |format|
code = params[:code]
unless code.blank?
[..]
load = { code: code, client_id: client_id, client_secret: client_secret, grant_type: grant_type, redirect_uri: redirect_uri }
url = "https://www.googleapis.com/oauth2/v3/token/"
response = HTTParty.post(url, :query => load, headers: { "content-type" => "application/x-www-form-urlencoded"})
json = JSON.parse(response.body)
unless json.nil?
unless json["error"].present?
[..]
email = decoded_hash["email"]
user = User.find_by_email(email)
if user
sign_in_existing_user(user)
format.json { render :json => {:status => "Success", user_id: "# {user.id}"} }
else
# Create user
[..]
format.html { redirect_to current_user, notice: "Welcome #{current_user.name}!" }
format.json { render :json => {:status => "Success", user_id: "#{current_user.id}"} }
end
else
#format.html { redirect_to root_path, error: "Could not sign up / in" }
format.json { head :no_content }
end
end
end
end
end
我已经根据@EugZol 的以下回答更新了我的 JS,更新为:
data: {access_token: response['access_token'], error: response['error'], expires_in: response['expires_in']}
我目前收到以下错误:
Started POST "/auth/google_oauth2/callback" [..]
Processing by UsersController#google_authentication as JSON
Parameters: {"expires_in"=>"86400", "provider"=>"google_oauth2"}
Completed 406 Not Acceptable in 1ms (ActiveRecord: 0.0ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/users_controller.rb:237:in `google_authentication'
我唯一可以假设的是,当您尝试向您自己的服务器发出请求时:
data: response
...您的代码正在以间接方式访问由 GAPI 创建的框架。即,response
对象在其框架的内部字段之一中引用,并且 jQuery 正在尝试对其进行序列化。
解决方案是手动选择必填字段:
data: {
state: response['state'],
code: response['code'],
scope: response['scope'],
client_id: response['client_id'],
g_user_cookie_policy: response['g_user_cookie_policy']
}
我有一个 Rails 应用程序,它使用 Google SSO 来登录/注册用户。它在 Safari 中运行良好,但在 Chrome 中我不断收到此错误:
Blocked a frame with origin "[domain]" from accessing a frame with origin "https://accounts.google.com". Protocols, domains, and ports must match.
我之前用这个"solution"解决过:https://github.com/zquestz/omniauth-google-oauth2/issues/122#issuecomment-60510241
但我最近注意到它突然停止使用上述解决方案来代替 Safari。
我当前的实现如下所示(咖啡脚本):
$(document).ready ->
$.ajax
url: 'https://apis.google.com/js/client:plus.js?onload=gpAsyncInit'
dataType: 'script'
cache: false
window.gpAsyncInit = ->
$('.googleplus-login').click (e) ->
e.preventDefault()
gapi.auth.authorize {
immediate: false
response_type: 'code'
cookie_policy: 'single_host_origin'
client_id: '[id]'
scope: 'email profile'
}, (response) ->
if response and !response.error
# google authentication succeed, now post data to server and handle data securely
jQuery.ajax
type: 'POST'
url: '/auth/google_oauth2/callback'
dataType: 'json'
data: response
success: (json) ->
# response from server
[this doesn't happen]
return
else
# google authentication failed
我在 Google 的文档中没有看到任何地方描述这个错误,所以我不太确定如何修复它。
我确定我有相同的协议 https
,所以它一定是别的东西。我猜是域名。
我看到其他网站(如 Stack-overflow)使用不同的流程,其中不显示弹出窗口,而是将用户重定向到另一个页面。想知道这是否可以作为解决方案(和/或)推荐的方法来避免我的错误。
在那种情况下,我可以在 Google 的文档丛林中的何处找到相关文档?
更新
这是我的控制器代码的相关部分。
def google_authentication
respond_to do |format|
code = params[:code]
unless code.blank?
[..]
load = { code: code, client_id: client_id, client_secret: client_secret, grant_type: grant_type, redirect_uri: redirect_uri }
url = "https://www.googleapis.com/oauth2/v3/token/"
response = HTTParty.post(url, :query => load, headers: { "content-type" => "application/x-www-form-urlencoded"})
json = JSON.parse(response.body)
unless json.nil?
unless json["error"].present?
[..]
email = decoded_hash["email"]
user = User.find_by_email(email)
if user
sign_in_existing_user(user)
format.json { render :json => {:status => "Success", user_id: "# {user.id}"} }
else
# Create user
[..]
format.html { redirect_to current_user, notice: "Welcome #{current_user.name}!" }
format.json { render :json => {:status => "Success", user_id: "#{current_user.id}"} }
end
else
#format.html { redirect_to root_path, error: "Could not sign up / in" }
format.json { head :no_content }
end
end
end
end
end
我已经根据@EugZol 的以下回答更新了我的 JS,更新为:
data: {access_token: response['access_token'], error: response['error'], expires_in: response['expires_in']}
我目前收到以下错误:
Started POST "/auth/google_oauth2/callback" [..]
Processing by UsersController#google_authentication as JSON
Parameters: {"expires_in"=>"86400", "provider"=>"google_oauth2"}
Completed 406 Not Acceptable in 1ms (ActiveRecord: 0.0ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/users_controller.rb:237:in `google_authentication'
我唯一可以假设的是,当您尝试向您自己的服务器发出请求时:
data: response
...您的代码正在以间接方式访问由 GAPI 创建的框架。即,response
对象在其框架的内部字段之一中引用,并且 jQuery 正在尝试对其进行序列化。
解决方案是手动选择必填字段:
data: {
state: response['state'],
code: response['code'],
scope: response['scope'],
client_id: response['client_id'],
g_user_cookie_policy: response['g_user_cookie_policy']
}