1

在 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 之后我还是一头雾水,所以我想为可能也困惑的人补充一点解释。

它的工作方式:

  1. Facebook SDK 在页面加载时初始化。
  2. 用户单击“使用 Facebook 登录”链接。
  3. FB.login函数由链接调用,用户完成所有权限过程(例如,出现权限对话框询问用户权限)。
  4. 然后,用户被定向到/auth/facebook/callback。从routes.rb我们有线match 'auth/:provider/callback', to: 'sessions#create'。因此,现在服务器要么创建一个新用户,要么只创建一个会话,如果用户之前已经注册过。
  5. 完毕!用户已登录。

合并服务器端和客户端授权有两个主要优点: 1. 如果用户在 Facebook 内部(通过 appcenter)登录到应用程序,他也会在 Facebook 外部登录到应用程序。反之亦然,如果用户在 Facebook 外部登录,之后在 Facebook 内部访问,他将自动登录。2./auth/facebook如果用户在 Facebook iFrame 中登录,则无法登录。为了防止点击劫持,Facebook 禁止提示用户在 Facebook iFrame 中验证权限对话框。避免这种情况的唯一方法是在单独的弹出窗口中打开对话框,然后登录FB.login解决问题。

4

2 回答 2

1

它只是说,

Facebook 提供了一个 JavaScript SDK,我们可以使用它在客户端对用户进行身份验证,这样他们就不会觉得他们离开了我们的应用程序然后又返回了。

这意味着这是为了客户端理解,当用户从应用程序返回时,看起来他们确实没有离开它。

于 2013-02-19T08:30:51.680 回答
1

简短的回答是 - 你没有。
您可以在客户端登录(通过javascript SDK )和使用omniauth的服务器端登录之间进行选择。
服务器端登录的缺点是使服务器过载,您可以从客户端进行调用。
优点是通常令牌更长(3个月令牌而不是像客户端那样的1-2小时)。
我建议将两者结合起来。使用客户端进行初始登录,一旦你这样做了,服务器端就会对扩展令牌进行异步调用(仅当你必须这样做时)。

于 2013-02-19T09:14:42.280 回答