JWT 是 Json Web Token(以下简称 token) 的简称,阿里云函数目前公测 JWT 认证方式。
JWT 是一段字符串,由三部分组成,分别是 Header、Payload、Signature,中间用 .
隔开,即:
xxxxx.yyyyy.zzzzz
其中 Header 格式固定,就是下面这样的:
{
"alg": "HS256", //加密算法,可以是 "RS256" 等
"typ": "JWT" //固定不变
}
Payload 规定了多个固定的字段,例如 exp
字段表示 token 的过期时间,除了固定字段外,开发者可以根据需求自行添加其他字段。
{
"sub": "1234567890", //固定字段,subject identifier
"iat": 1516239022, //固定字段,issued at,令牌的颁发时间
"name": "John Doe", //开发者添加的字段
"admin": true //开发者添加的字段
}
注意上面的 xxxxx
、yyyyy
不是 json 字符串,而 Header、Payload 是,所以要用 Base64Url 把它们转换为更干净的字符串才能拼接在一起。Base64Url 是 base64 的衍生版,因为 base64 有少数字符不适合在 url 使用,例如 +
、/
,Base64Url 可以避免生成这些字符。
第三部分,即 Signature,是对 Header、Payload 的签名,签名算法在 Header 规定,签名密钥由开发者自行生成,对于 node.js,签名密钥可以这样快速生成:
const key = require("crypto").randomBytes(64).toString("hex");
不过阿里云函数的 JWT 认证要求使用一种叫 JWK(Json Web Key)的签名密钥,所以上面这种快速生成的密钥不能填入阿里云函数的设置页。JWK 密钥生成方式有很多,比如可以用 mkjwk.org 在线生成。
JWT、JWK 是同一套体系下的两个概念:
当你确认了 Header、Payload 并获得了一个签名密钥,就可以生成 Json Web Token(JWT)了,开源社区有很多库可以帮助你生成 JWT,例如 jsonwebtoken,你也可以把这三个信息粘贴到 JWT Debugger 快速生成 JWT,方便测试。
在 JWT Debugger 顶部选择签名算法,阿里云函数的文档使用 RS256 作为例子,所以这里也用 RS256 吧。在 Debugger 下方的 Private、Public key 输入框,可以看到 JWT 支持使用多种密钥生成,其中就包括 JWK。
JWT 认证适用于 HTTP 触发器,调用方发起 HTTP 请求时需要携带 Json Web Token 参数,函数触发器会先对 token 进行验证,验证通过了才会执行函数。
前面已经讲了 token 的生成方式,但这里还有一个问题:token 由谁提供?token 是一个敏感参数,不能在前端生成,只能放在后端,而且 token 必须有时效性,最好尽量短。所以开发者可以设立一个独立的接口,让前端传入一些参数(例如用户名和密码)换取 token。这是一种方式,具体采用什么方式应该根据具体的业务场景决定。
向客户颁发 token 的形式由用户根据具体的业务场景决定,可以将颁发 token 的功能部署到生产环境,配置成普通 API 后由访问者通过用户名密码获得,也可以直接在本地环境生成 token 后,直接拷贝给指定用户使用。出处
以下是阿里云 fc 开启 JWT 认证的操作步骤:
Bearer
前缀,建议 Bearer 后加一个空格,即 Authentication: "Bearer ${token}"
,你也可以放在 url query 发起请求,前面已经说过,token 经过 Base64Url 处理,可以安全地放在 url;在阿里云函数中,我们不需要对调用方发送过来的 token 进行验证,因为 HTTP 触发器帮我们做了。如果你希望自己实现 token 的验证,也可以使用前面提到的各种库实现。
JWT 最好设置较短的有效时间,过期后可以使用 refresh_token 获取新的 JWT。关于 refresh_token 的作用,可以看 stack overflow 的这个提问,以及这个 Youtube 视频。
相关文章: