国际化常见快捷登录总结:使用 Google、Facebook 等三方平台实现快速登录

背景

最近我们的产品要加用户系统,自己注册太麻烦,所以初期只支持 Google、Facebook 快捷登录。

服务端实在是缺人,于是这个任务就交给我了。

概览

快捷登录的流程都差不多,关键在于以下三个步骤:

  1. 在第三方平台(例如 Google)上申请一个支持快捷登录的 App,记录下 App ID 和 App Secret;
  2. 前端调用第三方平台登录服务,并使用自己的 App ID 作为参数。登录成功之后拿到一个 accessToken(名字可能不叫这个,但都是一回事),以及一些其他的用户信息(包括用户名、头像);
  3. 服务端拿到前端传来的 accessToken,调用第三方平台的校验服务,并使用自己的 App Secret 作为参数。拿到的解析结果包含三方平台的 userId,由此也就知道了前端用户是一个有效的第三方平台用户。

下面会分别看看几个常见的提供快捷登录服务的平台。

Google

这几种登录方式里面,我觉得 Google 是对开发者最友好的,文档清晰易读。从对快捷登录一窍不通,到读懂 Google 的文档、调通 Google 登录的流程,我只用了短短几个小时。

步骤 1:申请 App

这一步不是我做的,我接手的时候已经申请好了测试环境,线上环境还在审核中(感觉审核了挺久的)。

步骤 2:前端获取 idToken

通过 Firebase 接入

对于这一步,官方给出的文档是:Integrating Google Sign-In into your web app,从如何调用 SDK 到如何渲染登录按钮,都介绍得很详细。

但我们的前端没有通过上面方法接入 Google 校验服务。我在看前端代码的时候(因为我之前是做前端的,在开发过程中一般会在本地同时起服务端和前端这两个服务,自己跟自己联调),发现前端是通过 Firebase 接入的。

通过 Firebase 接入的好处是,前端只需要同样一套代码,就可以接入包括 Google、Facebook、Twitter 在内的一大批第三方用户校验服务,只需要在 Firebase 后台把相关的 App ID 等信息维护好就可以了。这样就省去了为每个不同校验方式分别编写校验方法的麻烦,可以说让开发和维护都省事了不少。

参考文档:Firebase Authentication

为什么是 idToken

前面说过,这一步拿到的一般是 accessToken,但不同第三方用户校验服务返回的 token 类型也不同,Google 在 accessToken 之外还返回了信息更丰富的 idToken,所以这里我们使用 idToken;而比如 Facebook 就只返回了 accessToken

步骤 3:服务端校验 idToken

Google 为多种服务端语音都提供了能够校验 idToken 的 SDK。参考链接:Authenticate with a backend server

以 Java 为例,可以添加以下 Maven 依赖:

<dependency>
  <groupId>com.google.api-client</groupId>
  <artifactId>google-api-client</artifactId>
  <version>1.32.1</version>
</dependency>

Google 官方文档中提供的校验示例:

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

...

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    // Specify the CLIENT_ID of the app that accesses the backend:
    .setAudience(Collections.singletonList(CLIENT_ID))
    // Or, if multiple clients access the backend:
    //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
    .build();

// (Receive idTokenString by HTTPS POST)

GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
  Payload payload = idToken.getPayload();

  // Print user identifier
  String userId = payload.getSubject();
  System.out.println("User ID: " + userId);

  // Get profile information from payload
  String email = payload.getEmail();
  boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
  String name = (String) payload.get("name");
  String pictureUrl = (String) payload.get("picture");
  String locale = (String) payload.get("locale");
  String familyName = (String) payload.get("family_name");
  String givenName = (String) payload.get("given_name");

  // Use or store profile information
  // ...

} else {
  System.out.println("Invalid ID token.");
}

但这里有个问题,就是官方文档里没说这里的 transportjsnoFactory 是什么。实测之后发现,可以写成下面这样:

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new GsonFactory())

这样就能跑通了。

Facebook

Facebook 的流程和 Google 几乎完全一样,但文档难读而且有问题,导致我在开发过程中踩了大坑,耽误了好几小时。

步骤 1:申请 App

这一步也不是我做的,我接手的时候连线上环境都通过审核了。

步骤 2:前端获取 accessToken

这一步仍然是通过 Firebase 接入的,参加前面 Google 部分。

步骤 3:服务端校验 accessToken

官方文档:Inspecting Access Tokens

这一步就有坑了。我调用官方文档上的 accessToken 校验服务(即步骤 3)接口:

GET graph.facebook.com/debug_token?
     input_token={token-to-inspect}
     &access_token={app-token-or-admin-token}

结果一直返回 500 错误。由于没有错误信息,我翻来覆去试了多种方法尝试解决都没有成功。

在这一步浪费了很多时间之后,最后终于用网上找到的另一个接口调通了:

GET https://graph.facebook.com/me?access_token=xxxxxxxxxxxxxxxxx

参考链接:How to verify Facebook access token?

然而我最终也没找到官方文档对该接口的记录。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值