FB社交登录PHP-为什么人们认为它如此困难


FB social Login PHP - Why People take it as so difficult?

我在基于PHP的网站中实现了FB social登录。我查看了FB网站,发现它很容易实现。以下是我所遵循的方法,我不确定这里是否存在任何安全问题

我使用过Facebook JS SDK的方法。

如下所示:

var appID = 'xxxxxxxxxxxxxxx';
window.fbAsyncInit = function() {
FB.init({
  appId      : appID, // App ID
  channelUrl : '',
  status     : true,
  cookie     : true,
  xfbml      : true, 
}); 
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
    // connected
    FB.api('/me?fields=id,name,email,permissions', function(response) {
        //alert('Good to see you, ' + response.name + '.');
    });
}else{
}
});
};
function login() {
  if( navigator.userAgent.match('CriOS') ){ 
  }
  else{
  FB.login(function(response) {
      if (response.authResponse) {
          replace_login();
      } else {
          // cancelled
          alert('User cancelled login or did not fully authorize.');
      }
  },{scope: 'email,public_profile,user_friends'});
}
}
function replace_login(){
   FB.api('/me?fields=id,name,email', function(response) {
       $.ajax({
          url: "s-account",
          type: 'POST',
          data: response,
          dataType: 'json',
          beforeSend: function(){
              $("#signin_fb").button('loading');
          },
          success: function(data) {
             $("#signin_fb").button('reset');
             window.location.reload();
          },
          error: function(){
              $("#signin_fb").button('reset');
          }
       });
   });
}

在服务器端的PHP中,我通过ajax调用将social_id, name and email等用户详细信息存储在数据库中,如果DB操作成功,那么我将用username and email在我的网站中设置Session Variable,用户将成功登录。

对于注销,我使用我自己的注销功能来破坏网站用户会话,用户成功注销。

现在,安全风险在哪里?因为如果用户注销,然后尝试再次登录,JS SDK将通过新的响应获得新的访问令牌。

整个身份验证过程可以归结为对s-account的ajax调用。您在POST请求中从FB.api()向后端应用程序发送名称电子邮件,正如您没有提到的,我认为您没有在服务器端使用这些详细信息验证访问令牌,您只是根据这些详细信息进行会话。

安全问题

现在,安全问题是您在服务器端使用客户端身份验证。用户可以简单地生成一个到s-account的POST请求,并使用任何用户名电子邮件地址的虚假响应(如Facebook),您的PHP应用程序将对用户进行身份验证并进行有效会话,而无需验证详细信息是否来自合法来源。您的身份验证在此阶段完全被破坏,因为恶意用户可以使用任何电子邮件用户名s-account生成简单的POST请求,从而使用任何帐户登录。

如何修复

Facebook在图中提供了一个端点API,该端点验证访问令牌并返回与该访问令牌相关联的用户的详细信息。来自文档:

此端点返回有关给定访问令牌的元数据。这包括数据,例如为其颁发令牌的用户令牌仍然有效,何时过期,以及应用程序为给定用户提供了。

Fb.Login()将生成访问令牌response.authResponse.accessToken和用户ID response.authResponse.userID。您需要发送此accessToken&userID以及对s-account的ajax调用中的其他用户详细信息,然后使用以下API端点来验证这些详细信息是否合法。

curl -X GET "https://graph.facebook.com/v2.6/debug_token?input_token=USER_ACCESS_TOKEN_FROM_AJAX_CALL&access_token=YOUR_APP_ACCESS_TOKEN"

如果访问令牌有效,您将获得以下响应,其中包含为其颁发此令牌的userID。

{
  "data": {
    "app_id": "YOUR_APP_ID",
    "application": "YOUR_APP_NAME",
    "expires_at": 1462777200,
    "is_valid": true,
    "scopes": [
      "email",
      "manage_pages",
      "pages_messaging",
      "pages_messaging_phone_number",
      "public_profile"
    ],
    "user_id": "THE_USER_ID_ASSOCIATED_WITH_THE_TOKEN"
  }
}

现在,您可以将这个userID与您在ajax调用中收到的userID进行比较,并检查详细信息是否合法。

如何获取APP_ACCESS_TOKEN

要使用debug_token API调试用户访问令牌,您需要使用以下API端点在服务器端生成APP访问令牌。

curl -X GET "https://graph.facebook.com/v2.6/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials"

这将返回您的应用访问令牌作为响应。

{
  "access_token": "YOUR_APP_ACCESS_TOKEN_HERE",
  "token_type": "bearer"
}