跳转到主要内容

准备向 API 发起已验证的请求

创建并配置服务账号后,您的应用程序需要完成以下步骤:

  1. 创建 JSON Web Token(JWT),其中包含头部(header)、负载(payload)和签名(signature);
  2. 向 OAuth2 身份验证平台请求访问令牌(AccessToken);
  3. 处理身份验证平台返回的 JSON 响应。

如果响应中包含访问令牌,您就可以使用它向该服务账号有权限访问的 Unico 产品 API 发起请求。(如果响应中不包含访问令牌,则可能是您的 JWT 和令牌请求有误,或者该服务账号没有访问所请求资源的必要权限。)

上述请求生成的访问令牌默认有效期为 3600 秒,但这可能因贵公司设置的安全配置而有所不同。当访问令牌过期时,您的应用程序应生成一个新的 JWT,对其签名,并向身份验证平台请求一个新的访问令牌。

1 — 创建 JWT

JWT 由三部分组成:头部负载签名。头部和负载均为 JSON 对象。这些 JSON 对象先以 UTF-8 序列化,然后使用 Base64url 编码¹。这种编码方式在重复编码操作的情况下能提供更强的抗变化能力。头部、负载和签名之间用句点(.)字符连接。

JWT 的组成方式如下:

{Base64url 编码的头部}.{Base64url 编码的负载}.{Base64url 编码的签名}

用于签名的基础文本组成方式如下:

{Base64url 编码的头部}.{Base64url 编码的负载}

1.1 — 构造 JWT 头部

头部由两个字段组成,用于指定签名算法和令牌格式。这两个字段均为必填项,且每个字段只有一个取值。服务账号依赖 RSA SHA-256 算法和 JWT 令牌格式。因此,头部的 JSON 表示如下:

{"alg":"RS256","typ":"JWT"}

其 Base64url 表示如下:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

1.2 — 构造 JWT 负载

JWT 负载包含关于该 JWT 的信息,包括请求的权限(作用域)、发起访问请求的账号、签发者、令牌签发时间以及令牌的有效期。大多数字段均为必填项。与 JWT 头部一样,负载也是一个 JSON 对象,并参与签名的构成。

1.3 — 必填字段

JWT 中的必填字段如下表所示。它们在负载中可以以任意顺序出现。

名称描述
iss公司内该服务账号的标识符。
scope应用程序所请求权限的列表,以空格或加号(+)分隔。如果需要该账号的全部权限,请使用星号(*)符号。
aud签发访问令牌的身份验证平台地址。该值应始终精确为 https://identityhomolog.acesso.io。常见的无效写法包括:添加末尾斜杠(https://identityhomolog.acesso.io/),或使用 HTTP 而非 HTTPS。
exp令牌的过期时间,以自 1970 年 1 月 1 日 00:00:00 UTC 起的秒数表示。该值的最长时长为 JWT 签发时间之后的 1 小时。它必须是数值型——像 "1524161193" 这样加引号的值属于字符串,将无法生效;1524161193 属于数字,可以生效。
iatJWT 的签发时间,以自 1970 年 1 月 1 日 00:00:00 UTC 起的秒数表示。该值必须是数值型,规则与 exp 相同。

iat 字段必须以所需格式表示当前时间,exp 字段必须遵循以下计算方式:

exp = iat + 3600

JWT 负载中必填 JSON 字段的表示如下:

{
"iss": "service_account_name@tenant_id.iam.acesso.io",
"aud": "https://identityhomolog.acesso.io",
"scope": "*",
"exp": 1626296976,
"iat": 1626293376
}

1.4 — 计算签名

**JSON Web 签名(JWS)**²规范是指导 JWT 签名计算的机制。用于签名计算的输入内容是以下内容的字节数组:

{Base64url 编码的头部}.{Base64url 编码的负载}

计算签名时必须使用 JWT 头部中指定的相同算法。OAuth2 身份验证平台唯一支持的签名算法是使用 SHA-256 的 RSA,在 JWT 头部的 alg 字段中表示为 RS256

使用与该服务账号一同创建并关联的私钥(从邮件收到的请求中生成的 .key.pem 文件),采用 SHA256withRSA(也称为使用 SHA-256 哈希的 RSASSA-PKCS1-V1_5-SIGN)对输入内容的 UTF-8 表示进行签名。输出内容将是一个字节数组。

随后需要将该签名进行 Base64url 编码。头部、负载和签名应以句点字符连接。结果即为该 JWT。

也可以使用现有的库来创建 JWT。作为参考,您可以在 jwt.io 网站上找到相关库的列表。

2 — 请求访问令牌

生成已签名的 JWT 后,应用程序即可使用它来请求访问令牌。访问令牌请求是一个 POST HTTPS 请求,其请求体应进行 URL 编码。URL 如下所示:

https://identityhomolog.acesso.io/oauth2/token

以下参数在 POST HTTPS 请求中为必填项:

名称描述
grant_type使用以下文本,如有必要请进行 URL 编码:urn:ietf:params:oauth:grant-type:jwt-bearer
assertion该 JWT,包括签名。
POST /oauth2/token HTTP/1.1
Host: identityhomolog.acesso.io
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<jwt>

3 — 处理身份验证平台的响应

如果 JWT 和访问令牌请求格式正确,且该服务账号具有必要的权限,身份验证平台将返回一个包含访问令牌的 JSON 对象:

{
"access_token": "<access_token>",
"token_type": "Bearer",
"expires_in": "3600"
}

JSON 对象的 access_token 字段中返回的访问令牌本身也是一个 JWT 令牌,应在 Unico 产品的 API 中使用。如果请求过程中发生错误,请在身份验证错误中查看错误类型。

4 — 访问令牌的有效期

访问令牌的有效期是可变的。其时长在与访问令牌一同返回的 expires_in 字段中指定。在其有效期内,应对所有产品 API 调用使用同一个访问令牌。

在当前令牌的有效期即将结束之前,请勿请求新的访问令牌。 我们建议预留 600 秒(10 分钟)的余量:

new Date((token.exp - 600) * 1000)

其中 token.exp 是该令牌的过期时间戳。

备注

默认情况下,发送给公司的令牌有效期为 1 小时,但该时长可以更改。建议始终以 expires_in 为基准,并从中减去 600 秒后再请求新令牌。

示例:

标准场景:
expires_in: 3600(1 小时)— 令牌于 14:42 生成
仅在 15:32 才请求新令牌,即 14:42 + (3600 - 600)
时长被修改的场景:
expires_in: 7200(2 小时)— 令牌于 14:42 生成
仅在 16:32 才请求新令牌,即 14:42 + (7200 - 600)
警告

请勿使用固定时间来获取新令牌,因为收到的令牌有效期可能短于设定的时间,这可能导致使用服务时出现故障。


¹ 根据 RFC 4648 中关于 BaseN 编码的规定,Base64url 格式与 Base64 类似,区别在于省略了 = 字符,并将 +/ 字符分别替换为 -_。 ² JSON Web 签名:https://tools.ietf.org/html/rfc7515