Facebook 登陆

发布时间 2023-05-03 21:25:07作者: 景小布

Facebook登陆

说句题外话:其实知道怎么写以后,写代码是相较简单的,比较难得地方是不知道该去哪找参考资料,如果遇见问题或者是难点去哪解决,所以每次写博客的时候尽量详细写一些找资料的过程,代码部分反而是其次的。

接下来就开启我们的Facebook登陆之旅

官方文档

  • 首先登陆官方的开发者平台开发者平台
  • 直接在页面上点击登陆详情或者顶部导航栏文档-登陆都可,如果要找其他文档直接进入文档地址
  • 进入登陆文档,可以看看概览什么的,或者可以直接进入指南Guides
  • Graph API,在 Facebook 开放平台中存取数据,服务端获取用户信息会用到

访问口令

下面介绍一下各种访问口令,我这边之前做过Facebook广告数据的获取用到其他类型的访问口令,所以这边都介绍一下

用户访问口令


应用任何时候以特定用户身份调用 API 读取、修改或写入该用户的 Facebook 数据时,都需要此类访问口令。通常可通过登录对话框获得用户访问口令,并且应用需征得用户允许才能获取此口令。

这个也是咱们使用Facebook登陆要用到的

用户访问口令分为两种形式:短期有效口令和长期有效口令。短期有效口令的有效期通常为一至两个小时,长期有效口令的有效期通常为60天左右。这些有效期也不是一直维持不变;有效期可能会在不发出警告的情况下发生更改,也有可能会提前到期。

提示:
通过网页登录生成的访问口令是短期有效口令,可以使用应用密钥执行服务器端API调用,将它们转换为长期有效口令。

使用 Facebook iOS 和 Android SDK 的移动应用默认获得长期有效口令。

应用访问口令


此类访问口令用于修改和读取应用设置,也可用于发布开放图谱操作。它使用应用与 Facebook 之间的预定义密钥生成,之后用于执行更改应用中各个设置的调用。可以通过服务器到服务器的调用获得应用访问口令。

提示:
应用访问口令用于代表应用而非用户请求 Facebook API。它可以用于修改应用参数、创建和管理测试用户,或者读取应用的成效分析。

生成应用访问口令

  • 应用编号
  • 应用密钥
代码示例
curl -X GET "https://graph.facebook.com/oauth/access_token
  ?client_id={your-app-id}
  &client_secret={your-app-secret}
  &grant_type=client_credentials"

还有一种方法可以向图谱 API 发出调用,并且不需要使用生成的应用访问口令。您可以在发出调用时以 access_token 参数的形式发送应用编号和应用密钥:

curl -i -X GET "https://graph.facebook.com/{api-endpoint}&access_token={your-app_id}|{your-app_secret}"  
警告:
选择使用生成的访问口令还是使用这种方法取决于您隐藏应用密钥的位置。

公共主页访问口令


此类访问口令与用户访问口令类似,区别在于该口令会向读取、写入或修改 Facebook 公共主页数据的 API 授予权限。如要获取公共主页访问口令,需要先获取用户访问口令,并请求公共主页权限或其他您需要的权限。拥有用户访问口令后,便可通过图谱 API 获取公共主页访问口令。

警告:
如要生成公共主页访问口令,公共主页管理员必须向应用授予公共主页权限或所需的其他权限。获得权限后,便可使用拥有必要权限的用户访问口令,检索公共主页访问口令。
curl -i -X GET "https://graph.facebook.com/{your-user-id}/accounts?access_token={user-access-token} 

客户端访问口令


客户端口令是可将其嵌入原生移动二进制文件或桌面应用以识别应用的标识符。客户端口令嵌入在应用中,因而不是密钥标识符。客户端口令用于访问应用层 API。客户端口令可在应用面板中找到。

重要:
从预计在 2022 年初发布的 iOS 和 Android SDK v13.0 开始,所有对图谱 API 的调用都将需要客户端口令。

与应用口令一样,客户端口令会代表应用而非用户发出Graph API 请求。

不同于其他口令,客户端访问口令无法单独在请求中使用,而须配合应用编号使用。如要执行此操作,请在应用编号末尾附加口令,并使用竖线 (|) 分隔:

{app-id}|{client-token}

例如:

access_token=1234|5678

如要获取应用的客户端访问口令,请执行以下操作:

  • 登录您的开发者帐户。
  • 在应用页面中选择一款应用,然后打开该应用的面板。
  • 在面板中,依次前往设置 > 高级设置 > 安全 > 客户端口令。

可移植性

上面我们看到了好多种访问口令,弄的乱乱的,不知到怎么使用了,可以参考一下可移植性文档做一个合适的了解以及选取

我们作为只是使用Facebook登陆,并且想要用户只要登陆授权一次,客户端登录状态就会保存不用频繁调用Facebook,那么就需要服务端来保存权限信息,并能读取、校验用户状态了,所以直接这里就选用的是:

在原生手机客户端或网页客户端登录。在服务器发出 API 请求(使用长期口令)。

正式开始

Facebook授权登陆(服务端)

Facebook配置

  • 注册成为开发者,在Facebook开发者官网注册成开发者
  • 点击右上角->我的应用->创建应用
  • 获取应用编号、应用密钥(后续开发使用)
  • 开通登录,点击左边产品->添加产品->登录
提示:
整个流程可以通过Facebook的API调试工具测试:

[用户信息获取入门指南](https://developers.facebook.com/docs/graph-api/get-started)

[API工具](https://developers.facebook.com/tools/explorer)

Facebook登陆流程图

登陆流程图

token校验

在使用访问口令时,需要检查与之相关的信息,如该口令的用户或有效期。如要获取此类信息,可使用Facebook的调试工具,或使用 API 端点。
调试和错误

访问api:

curl -i -X GET "https://graph.facebook.com/debug_token?input_token={input-token}&access_token={valid-access-token}
提示:
接口中的access_token和input_token均是客户端传递的token值

API 调用的响应为 JSON 数组,如下所示:

{
    "data":{
        "app_id":"{app-id}",
        "type":"USER",
        "application":"{app-name}",
        "data_access_expires_at":1576687825,
        "expires_at":1570820400,
        "is_valid":true,
        "scopes":[
            "pages_show_list",
            "public_profile"
        ],
        "granular_scopes":[
            {
                "scope":"pages_show_list",
                "target_ids":[
                    "{page-1-app-can-access-id}",
                    "{page-2-app-can-access-id}"
                ]
            }
        ],
        "user_id":"10215241773831025"
    }
}

如果是长期访问口令,则系统也会返回 issued_at 字段。

获取长期访问口令

默认的用户和主页访问口令为短期口令,会在数小时后过期,但可以使用短期口令交换长期口令

在使用 iOS、Android 或 JavaScript SDK 时,如果用户在最近 90 天使用过应用,SDK 会自动刷新口令。使用 Facebook SDK 的原生移动应用会获得有效期为 60 天左右的长期用户访问口令。当应用用户向 Facebook 服务器发出请求时,系统会每天刷新一次这些口令。如果未发出任何请求,口令就会在大约 60 天后过期,且用户必须再次登录才能获得新口令。

如果需要长期用户访问口令,可以从短期用户访问口令中生成。长期口令的有效期通常在 60 天左右。

需要准备以下各项:

  • 一个有效的用户访问口令
  • 应用编号
  • 应用密钥
    查询 GET oauth/access_token 端点。
curl -i -X GET "https://graph.facebook.com/{graph-api-version}/oauth/access_token?  
    grant_type=fb_exchange_token&          
    client_id={app-id}&
    client_secret={app-secret}&
    fb_exchange_token={your-access-token}" 

响应示例:

{
  "access_token":"{long-lived-user-access-token}",
  "token_type": "bearer",
  "expires_in": 5183944            //The number of seconds until the token expires
}

获取用户信息

Graph API是在 Facebook 开放平台中存取数据的主要方式。Graph API是一种基于 HTTP 的 API,应用可用其以编程方式查询数据,发布新动态,管理广告,上传照片和执行各种其他任务。
获取用户信息Graph API
接口请求地址:

curl -i -X GET \
  "https://graph.facebook.com/USER-ID?fields=id,name,email,picture&access_token=ACCESS-TOKEN"
注意事项
接口中的access_token指的是前面配置中获取的应用编号和应用密钥组合,值为{Your AppId}|{Your AppSecret}, 记得请求路径做urlEncode

官方工具

快使用官方工具试一试吧:
https://developers.facebook.com/tools/explorer/

很贴心,一进去就是登陆的请求

直接点击获取Generate Access Token:

可以看见官方请求的地址大概是这样

https://www.facebook.com/v16.0/dialog/oauth?response_type=token&client_id=127819966950874&redirect_uri=http://localhost:8093/jingxc/facebook/login/callback&scope=public_profile

也就是说我们修改redirect_uri就可以得到一个access_token,这里就相当于模拟客户端的请求登陆了,然后我们验证和获取用户信息

获取token

返回:

{
    "access_token":[
        "EAAB0QGe5rdoBAKP8v2u6sLXquobvqMtZCZBA084FkG0jQOTJGhY96A55rr6IXFnyI9s87AmKnftUfrpW1AnxPuhhUXXnYtCCSLa5B7oyVktYSqhx6KDzM9ey4DyoxJ1PoCcMcnB7liVPN8nMkrPqOMQRx9xyrLoKPh6OiIh8rLKNkpRvWDqcQkefwE6poh6zqygeJCJ2lM5yjZBeP0PDhkvChJuVeEdKpc0x9iySlk3ojd7QZCeVvyRlUONIRXoZD"
    ],
    "data_access_expiration_time":[
        "1690719298"//这个时间有两个月
    ],
    "expires_in":[
        "6302"
    ]
}

校验token

@Override
public ReturnResult checkToken(String accessToken) {
    String url = "https://graph.facebook.com/debug_token?input_token=" +
            accessToken + "&access_token=" + accessToken;

    Map<String, String> checkToken = client.getToMap(url, new HashMap<>(), new HashMap<>());

    System.out.println(JSON.toJSONString(checkToken));
    return ReturnResultSuccess.builder().code(ConstantCommon.RETURN_CODE_200).msg("success")
            .data(checkToken).build();
}

返回:

{
    "data":{
        "metadata":{
            "auth_type":"rerequest"
        },
        "expires_at":1682949600,
        "application":"LOGIN",
        "user_id":"200435082771639",
        "is_valid":true,
        "data_access_expires_at":1690719298,
        "scopes":[
            "public_profile"
        ],
        "type":"USER",
        "app_id":"127819966950874"
    }
}

获取用户信息

@Override
@OperationLogger
public ReturnResult checkUser(String accessToken, String userId) {
    String url = "https://graph.facebook.com/" + userId + "?fields=id,name"
            + "&access_token=" + accessToken;

    Map<String, String> checkUser = client.getToMap(url, new HashMap<>(), new HashMap<>());

    System.out.println(JSON.toJSONString(checkUser));
    return ReturnResultSuccess.builder().code(ConstantCommon.RETURN_CODE_200).msg("success")
            .data(checkUser).build();
}

返回:

{"name":"景兴春","id":"200435082771639"}
上面的accessToken均为用户登陆授权的token

获取用户信息也可以换成-应用访问口令

至此Facebook的登陆基本完成