在Ryan的Railscast Facebook授权中,他最后添加了一些Facebook SDK javascript,以“通过服务器端授权降低facebook客户端授权”。但是,我没有看到它的使用。如果我们已经使用omniauth从服务器端设置了授权,为什么我们必须再次添加客户端授权?它有什么不同?
引用的javascript代码是(来自链接的Railscast):
jQuery ->
$('body').prepend('<div id="fb-root"></div>')
$.ajax
url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js"
dataType: 'script'
cache: true
window.fbAsyncInit = ->
FB.init(appId: '<%= ENV["FACEBOOK_APP_ID"] %>', cookie: true)
$('#sign_in').click (e) ->
e.preventDefault()
FB.login (response) ->
window.location = '/auth/facebook/callback' if response.authResponse
$('#sign_out').click (e) ->
FB.getLoginStatus (response) ->
FB.logout() if response.authResponse
true
更新
我们需要将FB.login
授权与服务器端授权集成的原因之一可能是,如果在Facebook iFrame中访问Omniauth服务器端授权,则无法使用该授权。如果用户第一次访问应用程序,则应用程序必须请求权限;但是,无法在iFrame中加载oAuth权限对话框以防止点击劫持。调用FB.login
可以避免此类问题,因为它会将权限框显示为弹出窗口(Omniauth弹出选项不起作用)。
所以现在我有一个真正的理由来集成客户端授权,但Railscasts的代码不适用于我当前的设置。我选择以下列方式做到这一点。
现在,我的application.html.erb
中有以下脚本:
<script>
// Additional JS functions here
window.fbAsyncInit = function() {
FB.init({
appId : <%= ENV['FACEBOOK_KEY'] %>, // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
在我看来,我有以下链接调用Facebook登录行动:
<%= link_to 'log in with facebook', '/auth/facebook', id: 'fb_log_in_link' %>
我将以下脚本添加到我有登录链接的视图页面。
function login() {
FB.login(function(response) {
if (response.authResponse) {
window.location = '/auth/facebook/callback'
}
});
}
另外,我需要更改链接以调用函数,而不是指向/auth/facebook/
<%= link_to_function 'log in with facebook', 'login()' %>
完成!服务器端和客户端授权完全集成。由于在看完Ryan的Railscast之后我仍然感到困惑,我想为那些可能也感到困惑的人添加一些解释。
这种方式有效:
FB.login
函数由链接调用,用户将完成所有权限过程(例如,显示要求用户权限的权限对话框)。/auth/facebook/callback
。从routes.rb
我们就有match 'auth/:provider/callback', to: 'sessions#create'
行。因此,现在服务器将创建一个新用户,或者只是在用户之前已经注册过的情况下创建一个会话。合并服务器端和客户端授权有两个主要优点:
1.如果用户在Facebook内部(通过appcenter)登录应用程序,他也将登录Facebook外的应用程序。反之亦然,如果用户登录Facebook外,如果他在Facebook之后访问它,他将自动登录。
2.如果用户在Facebook iFrame中登录,则使用/auth/facebook
登录不起作用。为防止点击劫持 Facebook禁止提示用户在Facebook iFrame中进行身份验证权限对话框。避免这种情况的唯一方法是在单独的弹出窗口中打开对话框,使用FB.login
登录可以解决问题。
答案 0 :(得分:1)
它只是说,
Facebook提供了一个JavaScript SDK,我们可以使用它来验证客户端的用户,这样它就不会像他们离开我们的应用程序那样查看它们。
这意味着这是为了让客户端了解当用户从应用程序返回时,它看起来并不像他们确实离开了它。
答案 1 :(得分:1)
简短的回答是 - 你没有。
您可以选择客户端登录(通过javascript SDK)和服务器端登录使用omniauth。
服务器端登录的不足使服务器过载,以便您可以从客户端进行呼叫
优点是通常令牌更长(3个月令牌,而不是客户端1-2小时)
我建议combine the two。使用客户端进行初始登录,一旦你这样做,就可以从服务器端获得扩展令牌的异步调用(仅当你必须这样做时)。