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

FB社交登录PHP-为什么人们认为它如此困难?,php,facebook,facebook-graph-api,facebook-javascript-sdk,Php,Facebook,Facebook Graph Api,Facebook Javascript Sdk,我在基于PHP的网站上实现了FB社交登录。我查看了FB网站,发现它很容易实现。下面是我所采用的方法,我不确定这里是否存在任何安全问题 我使用了Facebook JS SDK方法 详情如下: var appID = 'xxxxxxxxxxxxxxx'; window.fbAsyncInit = function() { FB.init({ appId : appID, // App ID channelUrl : '', status : true, cookie

我在基于PHP的网站上实现了
FB社交
登录。我查看了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\u id、姓名和电子邮件
,如果DB操作成功,那么我将在我的网站中使用
用户名和电子邮件
设置
会话变量
,用户成功登录

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

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

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

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

安全问题

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

如何修复

Facebook在graph API中提供了一个端点,用于验证访问令牌并返回与此访问令牌关联的用户的详细信息。从:

此端点返回有关给定访问令牌的元数据。这 包括数据,例如为其颁发令牌的用户,是否 令牌在到期时仍然有效,并且具有哪些权限 应用程序已为给定用户配置了

Fb.Login()将生成访问令牌作为
response.authResponse.accessToken
和userId作为
response.authResponse.userId
。您需要将此
accessToken
&
userID
以及ajax调用中的其他用户详细信息发送到
s-account
,然后使用以下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"
如果访问令牌有效,您将获得以下响应,其中包含为其发出该令牌的用户标识

{
  "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进行比较,并检查详细信息是否合法

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"
如何获取应用程序访问令牌

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

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"
}

明亮的昨天,我用假数据解决了这个电话后问题,并解决了它。。但你的解释提供了更安全的解决方案。在哪里放置此
curl-X GET
以及什么是
您的应用程序访问\u令牌
。是应用程序ID吗?不是,应用程序访问令牌不是应用程序ID。阅读最后一节“如何获取应用程序访问令牌”。“curl-xget”表示对API的HTTP请求。您可以使用PHPs CURL()在服务器端发出此HTTP请求。首先,在POST
之后,需要执行如何获取应用程序访问令牌。。对吗?使用FB PHP SDK在这里也有帮助。。正确的?要得到所有这些细节?是的。。但是我不建议只对2-3个HTTP请求使用整个SDK。如果您计划稍后扩展该功能,那么您应该。是的,
APP\u ACCESS\u TOKEN
应该是服务器端ajax调用后的第一件事。