logo科技微讯

阿里云函数开启 JWT 认证

作者:科技微讯
日期:2023-04-22
📝 笔记

JWT 是 Json Web Token(以下简称 token) 的简称,阿里云函数目前公测 JWT 认证方式。

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 //开发者添加的字段
}

注意上面的 xxxxxyyyyy 不是 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 是同一套体系下的两个概念:

JOSE
JOSE

当你确认了 Header、Payload 并获得了一个签名密钥,就可以生成 Json Web Token(JWT)了,开源社区有很多库可以帮助你生成 JWT,例如 jsonwebtoken,你也可以把这三个信息粘贴到 JWT Debugger 快速生成 JWT,方便测试。

在 JWT Debugger 顶部选择签名算法,阿里云函数的文档使用 RS256 作为例子,所以这里也用 RS256 吧。在 Debugger 下方的 Private、Public key 输入框,可以看到 JWT 支持使用多种密钥生成,其中就包括 JWK。

jwt_debugger_key

云函数开启 JWT 认证

JWT 认证适用于 HTTP 触发器,调用方发起 HTTP 请求时需要携带 Json Web Token 参数,函数触发器会先对 token 进行验证,验证通过了才会执行函数。

JWT 认证流程
JWT 认证流程

前面已经讲了 token 的生成方式,但这里还有一个问题:token 由谁提供?token 是一个敏感参数,不能在前端生成,只能放在后端,而且 token 必须有时效性,最好尽量短。所以开发者可以设立一个独立的接口,让前端传入一些参数(例如用户名和密码)换取 token。这是一种方式,具体采用什么方式应该根据具体的业务场景决定。

向客户颁发 token 的形式由用户根据具体的业务场景决定,可以将颁发 token 的功能部署到生产环境,配置成普通 API 后由访问者通过用户名密码获得,也可以直接在本地环境生成 token 后,直接拷贝给指定用户使用。出处

以下是阿里云 fc 开启 JWT 认证的操作步骤

阿里云函数 JWT 设置界面
阿里云函数 JWT 设置界面
  1. 为函数开启 HTTP 触发器,在认证方式处选择“JWT 认证”;
  2. 接着填写“JWKS”,JWKS 是 JWK Set 的简称,即一组 JWK,JWK 前面已经讲过,就是密钥,对于非对称加密,这里填写的是公钥,私钥用于后端生成 token;
  3. 在“JWT Token 配置”处,告诉函数 token 将放在哪里发起请求?默认放在 header 的 Authentication 字段且使用 Bearer 前缀,建议 Bearer 后加一个空格,即 Authentication: "Bearer ${token}",你也可以放在 url query 发起请求,前面已经说过,token 经过 Base64Url 处理,可以安全地放在 url;
  4. 接着填写“JWT Claim 转换”,JWT Claim 就是 JWT 声明,Payload 的每个字段就是一个 Claim,转换的意思是把 Payload 中的某个叫 A 的字段转换(映射、改名)为 B 并作为参数传递给函数,如果你的函数不关注 Payload 中的数据,可以忽略这个项目;

在阿里云函数中,我们不需要对调用方发送过来的 token 进行验证,因为 HTTP 触发器帮我们做了。如果你希望自己实现 token 的验证,也可以使用前面提到的各种库实现。

结合 refresh_token 使用

JWT 最好设置较短的有效时间,过期后可以使用 refresh_token 获取新的 JWT。关于 refresh_token 的作用,可以看 stack overflow 的这个提问,以及这个 Youtube 视频


相关文章:

donation赞赏
thumbsup0
thumbsdown0
暂无评论