在沙箱环境中实现 JWT 生成与鉴权的完整流程

在沙箱环境中实现 JWT 生成与鉴权的完整流程

本文详细记录了我在沙箱环境中实现 JWT(JSON Web Token)生成与鉴权的整个过程,包括遇到的错误、解决方案,以及最终可用的代码示例。本文通过 Markdown 格式编写,方便在 CSDN 或其他博客平台发布。


目录

背景与需求遇到的问题与错误分析手动实现 JWT 生成沙箱异步函数实现生成的 JWT 如何鉴权总结


1. 背景与需求

在使用 Coze 平台的沙箱环境时,需要生成符合 RS256 签名的 JWT 用于接口鉴权。但因为沙箱环境不允许安装第三方库,必须实现纯 Python 的 JWT 生成,并且能在沙箱的异步函数中返回。

要求如下:

不依赖
pyjwt
或其他第三方库。能生成 RS256 签名的 JWT。JWT 必须在沙箱环境中异步调用。支持用户会话隔离。


2. 遇到的问题与错误分析

在实现过程中遇到了多个问题:

2.1 使用
pyjwt
在沙箱中失败

初始代码:


import jwt
jwt.encode(...)

问题:沙箱环境不允许安装
pyjwt

2.2 手动实现 RS256 签名失败

尝试手动用
hashlib
+
pow
进行 RSA 签名时,生成的 token 返回
invalid jwt: jwt token has been used
错误。

原因分析:

Coze 平台对
jti
(JWT ID)有重复判定。频繁生成 JWT 时,如果
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

jti
唯一。避免频繁调用导致判重。JWT 有效期 15 分钟(
exp = iat + 900
)。

请求示例:


{
    "jwt": "生成的token",
    "duration_seconds": 86399,
    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer"
}

6. 总结

沙箱环境不允许第三方库,需要手动实现 Base64 和 RSA 签名。JWT 生成时必须保证
iat

jti
唯一,否则会被判定重复。使用
async def main(args)
封装函数即可在沙箱环境中调用。本文提供的完整代码可直接生成有效 JWT 用于沙箱环境的接口调用。


以上就是沙箱中实现 JWT 生成与鉴权的完整流程。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容