利用 facebook 的 javascript SDK 来登录


Facebook 的上用户开发的 app可以利用几个不同方式来实现登录流程, 这个不同的方式取决于目标终端是什么.本文将会一步步介绍如何利用 javascript 的 SDK 来实现 web 页面上的登录.

###快速上手

此文会介绍如何一步步的爱实现登录流程, 会具体讲到每一步到底在干什么,这样会有利于你如果想要把 facebook 的登录集成到现有的 ID 系统中,让你修改最小的代码量.

在使用 facebook 的 sdk 之前,你需要有一个 appid, 这个你可以在[这里获取到,)(https://developers.facebook.com/apps/),同时你需要一些 html 的页面,如果没有的话,还可以通过使用这个 [parse](https://www.parse.com/products/core) 来搞定哦

下面的代码加载并实例化了 javascript 的 SDK在你的 html 页面中,

```html
<!DOCTYPE html>
<html>
<head>
<title>Facebook Login JavaScript Example</title>
<meta charset="UTF-8">
</head>
<body>
<script>
  // This is called with the results from from FB.getLoginStatus().
  function statusChangeCallback(response) {
    console.log('statusChangeCallback');
    console.log(response);
    // The response object is returned with a status field that lets the
    // app know the current login status of the person.
    // Full docs on the response object can be found in the documentation
    // for FB.getLoginStatus().
    if (response.status === 'connected') {
      // Logged into your app and Facebook.
      testAPI();
    } else if (response.status === 'not_authorized') {
      // The person is logged into Facebook, but not your app.
      document.getElementById('status').innerHTML = 'Please log ' +
        'into this app.';
    } else {
      // The person is not logged into Facebook, so we're not sure if
      // they are logged into this app or not.
      document.getElementById('status').innerHTML = 'Please log ' +
        'into Facebook.';
    }
  }

  // This function is called when someone finishes with the Login
  // Button.  See the onlogin handler attached to it in the sample
  // code below.
  function checkLoginState() {
    FB.getLoginStatus(function(response) {
      statusChangeCallback(response);
    });
  }

  window.fbAsyncInit = function() {
  FB.init({
    appId      : '{your-app-id}', //替换你的 app id
    cookie     : true,  // enable cookies to allow the server to access 
                        // the session
    xfbml      : true,  // parse social plugins on this page
    version    : 'v2.2' // use version 2.2
  });

  // Now that we've initialized the JavaScript SDK, we call 
  // FB.getLoginStatus().  This function gets the state of the
  // person visiting this page and can return one of three states to
  // the callback you provide.  They can be:
  //
  // 1. Logged into your app ('connected')
  // 2. Logged into Facebook, but not your app ('not_authorized')
  // 3. Not logged into Facebook and can't tell if they are logged into
  //    your app or not.
  //
  // These three cases are handled in the callback function.

  FB.getLoginStatus(function(response) {
    statusChangeCallback(response);
  });

  };

  // Load the SDK asynchronously
  (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));

  // Here we run a very simple test of the Graph API after login is
  // successful.  See statusChangeCallback() for when this call is made.
  function testAPI() {
    console.log('Welcome!  Fetching your information.... ');
    FB.api('/me', function(response) {
      console.log('Successful login for: ' + response.name);
      document.getElementById('status').innerHTML =
        'Thanks for logging in, ' + response.name + '!';
    });
  }
</script>

<!--
  Below we include the Login Button social plugin. This button uses
  the JavaScript SDK to present a graphical Login button that triggers
  the FB.login() function when clicked.
-->

<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>

<div id="status">
</div>

</body>
</html>

```

通过上面页面代码就实现了 facebook 的登录,然后你打开开发者工具在控制台里通过` testAPI()`这个函数就可以现实当前登录用户的信息了.

恭喜,到了这一步,你已经完成了一个基础的利用 facebook 登录的页面了. 可以用这个作为程序的起点然后不断让他羽翼丰满,

###利用 facebook 的 javascript SDK 来实现 facebook 登录的步骤

把 facebook 登录方式集成起来有好几个步骤.大部分的步骤现在已经在上面的例子中体现了.大致来讲就是下面的几个步骤:

1. 验证当前的登录状态, 来看看是否已经有人登录了.这个步骤中,需要验证当前是否已经有登录用户,而且和登录的用户不一样.
2. 如果他们没有登录,[触发 facebook 登录页面并且让他们授权](https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.2#logindialog)
3. 验证身份
4. 存储访问令牌
5. 访问 api
6. 登出


#####验证登录状态
第一步是要验证当前是否已经有人登录了.通过这个函数` FB.getLoginStatus`.这个函数会触发一个请求到 facebook, 来获取登录状态.然后回传结果给你.
下面的代码就是在页面加载之后触发的:

```javascript

FB.getLoginStatus(function(response) {
    statusChangeCallback(response);
});
```
这个`response` 对象提供了一个回调函数,包含了一组数据:

```javascript
{
    status: 'connected',
    authResponse: {
        accessToken: '...',
        expiresIn:'...',
        signedRequest:'...',
        userID:'...'
    }
}
```

- status 有下面几个状态:
	- connected
	- not_authorized
	- unknown
- authResponse 如果 status 是` connected`, 就会有这个属性.
	- accessToken
	- expiresIn
	- signedRequest
	- userID

如果这个 app 知道了当前的登录状态,它可以接下来做这些事情:

- 如果当前用户已经登录了.重定向
-  如果用户没有登录,那就提示他们登录通过` FB.login()`或者提示登录按钮.

##### 登录

如果当前用户没有登录,那就提示让他们登录,不同样式的弹出框.
有2种方式来让用户登录

- 通过登录按钮
- 通过` FB.login()`


###### 登录按钮

把登录按钮加载到你的页面是简单的活儿,通过[这个就可以搞定.](https://developers.facebook.com/docs/plugins/login-button), 直接通过配置就可以获取按钮的代码. 注意在之前的例子中,我们通过`onlogin` 这个属性来通过回调返回验证结果:

```javascript
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
```

这个是回调函数, 他调用了` FB.getLoginStatus`来获取最近的登录信息.(`statusChangeCallback() 这个函数是处理响应过程中的一个部分)

```javascript
function checkLoginState() {
  FB.getLoginStatus(function(response) {
    statusChangeCallback(response);
  });
}
```

######通过 javascript SDK 开触发登陆框

通过` FB.login()` 函数就能够触发一个用户可以自定义的登陆框.

```javascript
FB.login(function(response){
  // Handle the response object, like in statusChangeCallback() in our demo
  // code.
});
```

需要注意的是,这个就是通过一个按钮来触发一个弹出框,所以这个弹出框不能够被浏览器 block 了.
有一个` scope` 的可选参数,他是一个权限的 list, 通过逗号分隔的一个字符串.看下面的例子:

```javascript
 FB.login(function(response) {
   // handle the response
 }, {scope: 'public_profile,email'});

```
######处理弹框的响应
在整个登录的流程里,这个弹出告诉用户是否允许我们来访问他们的数据.
不管用户做出什么响应.浏览器都会返回一个响应.来表明他们是否接受或者取消授权. 当你的 app 使用 javascript 的 SDK 的时候, 他会返回一个`authResponse` 对象给回调函数.当你调用 `FB.login()`函数的时候. 看下面的代码:

```javascript
FB.login(function(response) {
  if (response.status === 'connected') {
    // Logged into your app and Facebook.
  } else if (response.status === 'not_authorized') {
    // The person is logged into Facebook, but not your app.
  } else {
    // The person is not logged into Facebook, so we're not sure if
    // they are logged into this app or not.
  }
});
```

######询问权限
弹框中最重要的部分就是让用户选择允许我们来访问什么数据. 这些数据都包含在了` scope` 参数中. 我们统称为`权限`
详细的关于权限的描述看[这里](https://developers.facebook.com/docs/facebook-login/permissions), 下面我们就简要看看:



######存储访问令牌

######身份验证

######API 访问

######登出

######追加权限

###### 再次询问降低权限

######检测是否卸载此 app


copy from https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.2