在沙箱环境中实现 JWT 生成与鉴权的完整流程
本文详细记录了我在沙箱环境中实现 JWT(JSON Web Token)生成与鉴权的整个过程,包括遇到的错误、解决方案,以及最终可用的代码示例。本文通过 Markdown 格式编写,方便在 CSDN 或其他博客平台发布。
目录
背景与需求遇到的问题与错误分析手动实现 JWT 生成沙箱异步函数实现生成的 JWT 如何鉴权总结
1. 背景与需求
在使用 Coze 平台的沙箱环境时,需要生成符合 RS256 签名的 JWT 用于接口鉴权。但因为沙箱环境不允许安装第三方库,必须实现纯 Python 的 JWT 生成,并且能在沙箱的异步函数中返回。
要求如下:
不依赖 或其他第三方库。能生成 RS256 签名的 JWT。JWT 必须在沙箱环境中异步调用。支持用户会话隔离。
pyjwt
2. 遇到的问题与错误分析
在实现过程中遇到了多个问题:
2.1 使用
pyjwt 在沙箱中失败
pyjwt
初始代码:
import jwt
jwt.encode(...)
问题:沙箱环境不允许安装 。
pyjwt
2.2 手动实现 RS256 签名失败
尝试手动用 +
hashlib 进行 RSA 签名时,生成的 token 返回
pow 错误。
invalid jwt: jwt token has been used
原因分析:
Coze 平台对 (JWT ID)有重复判定。频繁生成 JWT 时,如果
jti 时间相同或者
iat 太短,平台认为重复使用。
jti
解决方案:
增加 生成唯一
secrets.token_urlsafe。确保
jti 为当前时间戳。
iat
3. 手动实现 JWT 生成
在沙箱环境下,我们需要纯 Python 实现 Base64 URL-safe 编码和 PKCS#1 v1.5 RS256 签名:
import base64
import hashlib
import time
import secrets
import json
# RSA 私钥参数 n 和 d(从私钥提取的整数)
n = ...
d = ...
app_id = "1182370701058"
kid = "o3XdpVxqwz8YvwiC_LpD443quSLQL02hdYG0cEO_zFc"
def base64url_encode(data: bytes) -> str:
return base64.urlsafe_b64encode(data).rstrip(b"=").decode()
def rsa_sign(msg: bytes) -> bytes:
hash_bytes = hashlib.sha256(msg).digest()
sha256_prefix = bytes.fromhex("3031300d060960864801650304020105000420")
t = sha256_prefix + hash_bytes
k = (n.bit_length() + 7) // 8
ps = b'xff' * (k - len(t) - 3)
em = b'x00x01' + ps + b'x00' + t
em_int = int.from_bytes(em, 'big')
sig_int = pow(em_int, d, n)
return sig_int.to_bytes(k, 'big')
def generate_jwt(user: str) -> str:
header = {"alg":"RS256","typ":"JWT","kid":kid}
now = int(time.time())
payload = {
"iss": app_id,
"aud": "api.coze.cn",
"iat": now,
"exp": now + 900,
"jti": secrets.token_urlsafe(16),
"session_name": user
}
header_b64 = base64url_encode(json.dumps(header,separators=(',',':')).encode())
payload_b64 = base64url_encode(json.dumps(payload,separators=(',',':')).encode())
msg = f"{header_b64}.{payload_b64}".encode()
sig_b64 = base64url_encode(rsa_sign(msg))
return f"{header_b64}.{payload_b64}.{sig_b64}"
print(generate_jwt("testuser"))
4. 沙箱异步函数实现
在沙箱中调用时,需要将生成 JWT 的过程封装在 中:
async def main(args)
async def main(args):
params = args.params
user = params.get("input", "default_user")
jwt_token = generate_jwt(user)
now = int(time.time())
ret = {
"jwt": jwt_token,
"user": user,
"issued_at": now,
"expires_at": now + 900
}
return ret
特点:
获取沙箱传入参数。返回字典对象,包含
args.params、
jwt、
user、
issued_at。
expires_at
5. 生成的 JWT 如何鉴权
沙箱生成的 JWT 可直接用于 Coze 平台接口调用。注意:
每次生成要保证 和
iat 唯一。避免频繁调用导致判重。JWT 有效期 15 分钟(
jti)。
exp = iat + 900
请求示例:
{
"jwt": "生成的token",
"duration_seconds": 86399,
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer"
}
6. 总结
沙箱环境不允许第三方库,需要手动实现 Base64 和 RSA 签名。JWT 生成时必须保证 和
iat 唯一,否则会被判定重复。使用
jti 封装函数即可在沙箱环境中调用。本文提供的完整代码可直接生成有效 JWT 用于沙箱环境的接口调用。
async def main(args)
以上就是沙箱中实现 JWT 生成与鉴权的完整流程。






















暂无评论内容