在 Ryan 的Railscast on 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
授权与服务器端授权集成的原因之一可能是 Omniauth 服务器端授权在 Facebook iFrame 中访问时不起作用。如果用户第一次访问应用程序,应用程序必须请求权限;但是,无法在 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 之后我还是一头雾水,所以我想为可能也困惑的人补充一点解释。
它的工作方式:
- Facebook SDK 在页面加载时初始化。
- 用户单击“使用 Facebook 登录”链接。
FB.login
函数由链接调用,用户完成所有权限过程(例如,出现权限对话框询问用户权限)。- 然后,用户被定向到
/auth/facebook/callback
。从routes.rb
我们有线match 'auth/:provider/callback', to: 'sessions#create'
。因此,现在服务器要么创建一个新用户,要么只创建一个会话,如果用户之前已经注册过。 - 完毕!用户已登录。
合并服务器端和客户端授权有两个主要优点: 1. 如果用户在 Facebook 内部(通过 appcenter)登录到应用程序,他也会在 Facebook 外部登录到应用程序。反之亦然,如果用户在 Facebook 外部登录,之后在 Facebook 内部访问,他将自动登录。2./auth/facebook
如果用户在 Facebook iFrame 中登录,则无法登录。为了防止点击劫持,Facebook 禁止提示用户在 Facebook iFrame 中验证权限对话框。避免这种情况的唯一方法是在单独的弹出窗口中打开对话框,然后登录FB.login
解决问题。