我已经成功地将OmniAuth Facebook登录流集成到服务器端的rails应用程序中。然而,我也试图让它在客户端使用来工作,并且遇到了一些问题。
编辑:这个问题似乎只发生在CHROME中,而不是在SAFARI或FIREFOX中。
会话控制器-在服务器端流上工作
def create
auth = request.env['omniauth.auth']
#if an authorization does not exisit, it will create a new authorization record. it will also create a new user record if a user is not currently logged in
unless @auth = Authorization.find_from_hash(auth)
# Create a new user or add an auth to existing user, depending on
# whether there is already a user signed in.
@auth = Authorization.create_from_hash(auth, current_user)
#add the friends array to user record. as of now only doing this on the initial user create
@friends = []
FbGraph::User.me(@auth.user.authorization.facebook_token).fetch.friends.each do |t|
@friends << t.identifier
end
u = @auth.user
u.facebook_friends = @friends
u.save
end
#store a new auth token if needed (if the new token in the hash does not match the one stored in the database for authorization)
Authorization.check_if_new_auth_token_is_needed(auth)
# Log the authorizing user in.
self.current_user = @auth.user
redirect_to root_url
end如果我只点击/auth/facebook路径,用户将被登录
路线
match '/auth/:provider/callback', :to => 'sessions#create'现在,在主页视图中,我正在尝试运行客户端流登录。
主页查看
<script>
$(function() {
$('a').click(function(e) {
e.preventDefault();
FB.login(function(response) {
if (response.authResponse) {
$('#connect').html('Connected! Hitting OmniAuth callback (GET /auth/facebook/callback)...');
// since we have cookies enabled, this request will allow omniauth to parse
// out the auth code from the signed request in the fbsr_XXX cookie
$.getJSON('/auth/facebook/callback', function(json) {
$('#connect').html('Connected! Callback complete.');
$('#results').html(JSON.stringify(json));
});
}
}, { scope: 'email,publish_stream' });
});
});
</script>
<p id="connect">
<a href="#">Connect to FB</a>
</p>
<p id="results" />我的日志中有以下错误
{“错误”:{“消息”:“缺少授权代码”,“类型”:“OAuthException”,“代码”:1}
基本上,Omniauth并没有收到来自FB.login行动的facebook签名请求(正如https://github.com/mkdynamic/omniauth-facebook/blob/master/example/config.ru所说的那样)。
关于我如何使它正常工作或者我可能做错了什么?
发布于 2014-02-27 22:41:59
我意识到这个问题已经存在了一年,但我已经遇到了两次这个问题,所以希望这能帮助到一些人。
有两个与此问题相关的github线程:https://github.com/mkdynamic/omniauth-facebook/issues/73和https://github.com/intridea/omniauth-oauth2/issues/31
问题的根源在于万能OAuth2GEM中的callback_phase方法:
if !options.provider_ignores_state && (request.params['state'].to_s.empty? || request.params['state'] != session.delete('omniauth.state'))
raise CallbackError.new(nil, :csrf_detected)
endRequest.params‘’state‘和会话’Omauth.state‘都为零,因此条件失败,引发CallbackError异常。
一种解决方案是将provider_ignores_state设置为true,这绕过了条件:
config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'], {
strategy_class: OmniAuth::Strategies::Facebook,
provider_ignores_state: true,
}正如在上面的线程中所指出的,它不是一个永久的解决方案,因为它可以让您对csrf攻击保持开放。
另一件需要注意的事情是,Chrome在为本地主机编写cookie时遇到了问题。尝试使用lvh.me作为您的域(它解析为127.0.0.1)。
修补问题的更多代码通常不是一条很好的途径,但如果这两种解决方案都不起作用,那么您总是可以创建自己的处理程序并解析Facebook cookie:
def handle_facebook_connect
@provider = 'facebook'
@oauth = Koala::Facebook::OAuth.new(ENV["FACEBOOK_ID"], ENV["FACEBOOK_SECRET"])
auth = @oauth.get_user_info_from_cookies(cookies)
# Get an extended access token
new_auth = @oauth.exchange_access_token_info(auth['access_token'])
auth['access_token'] = new_auth["access_token"]
# Use the auth object to setup or recover your user. The following is
# and example of how you might handle the response
if authentication = Authentication.where(:uid => auth['user_id'], :provider => @provider).first
user = authentication.user
sign_in(user, :event => :authentication)
end
# Redirect or respond with json
respond_to do |format|
format.html { redirect_to user }
format.json { render json: user }
end
end然后,当收到连接的响应时,需要重定向到“handle_facebook_connect”方法:
FB.Event.subscribe('auth.authResponseChange', function(response) {
if(response.status === 'connected'){
if(response.authResponse){
// Redirect to our new handler
window.location = '/handle_facebook_connect';
// Or make an ajax request as in the code in the original question:
// $.getJSON('/handle_facebook_connect', function(json) {
// $('#connect').html('Connected! Callback complete.');
// $('#results').html(JSON.stringify(json));
// });
}
} else if (response.status === 'not_authorized'){
Facebook.message(Facebook.authorize_message);
} else {
FB.login();
}
});https://stackoverflow.com/questions/10320320
复制相似问题