Files
cpzs-backend/userController.txt
2025-08-01 19:09:57 +08:00

164 lines
6.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

2 签署 JWT
扣子的 JWT 生成方式及部分参数定义沿用业界统一流程规范,但 JWT 中 Header 和 Payload 部分由扣子平台自行定义。
在 JWTJSON Web Tokens的流程中通常使用私钥来签署signtoken。JWT 包含三部分,即 Header、Payload 和 signature其中 header 和 payload 由参数拼接而成signature 根据指定的签名算法和私钥对 Header 和 Payload 自动计算生成。三部分之间用点(.分隔。详细的签署方式可参考JWT 官方文档。
Header 和 Payload
扣子平台对 Header 和 Payload 的定义如下:
Header
Header 部分的参数定义如下:
参数
类型
是否必选
说明
alg
String
必选
签名使用的加密算法。固定为 RS256即非对称加密算法一种基于 RSA非对称加密算法+ SHA256安全哈希函数的签名算法该算法使用私钥进行签名公钥进行验证。
typ
String
必选
固定为 JWT。
kid
String
必选
OAuth 应用的公钥指纹可以在OAuth 应用页面找到这个应用,在操作列单击编辑图标,进入配置页面查看公钥指纹。
Header 示例如下:
{
"alg": "RS256", // 固定为RS256
"typ": "JWT", // 固定为 JWT
"kid": "gdehvaDegW....." // OAuth 应用的公钥指纹
}
Payload
Payload 部分的参数定义如下:
参数
类型
是否必选
说明
iss
String
必选
OAuth 应用的 ID可以在OAuth 应用页面查看。
aud
String
必选
扣子 API 的 Endpoint即 api.coze.cn。
iat
Integer
必选
JWT 开始生效的时间Unixtime 时间戳格式,精确到秒。一般为当前时刻。
exp
Integer
必选
JWT 过期的时间Unixtime 时间戳格式,精确到秒。必须晚于 iat。
jti
String
必选
随机字符串,用于防止重放攻击。建议长度大于 32 字节。每次签署 JWT 时应指定为不同的字符串。
session_name
String
可选
访问令牌的会话标识。目前仅限在会话隔离场景下使用,即将 session_name 指定为用户在业务侧的 UID以此区分不同业务侧用户的对话历史。
若未指定 session_name不同用户的对话历史可能会掺杂在一起。
会话隔离的详细实现方法请参见如何实现会话隔离。
session_context
Object
可选
会话上下文信息,包含设备相关信息等。
session_context.device_info
Object
可选
用于配置设备相关信息,扣子平台基于该部分信息对设备做用量管控以及账单记录。
该参数为企业白版白名单功能,需要联系扣子商务经理开通后才能使用。硬件设备用量管控的具体操作可参考硬件设备用量查询和配额管控。
session_context.device_info.device_id
String
可选
IoT 等硬件设备 ID一个设备对应一个唯一的设备号。
当需要记录设备用量或对设备用量进行管控时,需要填写该参数,否则,无法对设备进行用量管控,用量统计页面对应的设备 ID 将显示为 N/A。
session_context.device_info.custom_consumer
String
可选
自定义维度的实体 ID你可以根据业务需要进行设置例如 APP 上的用户名等。
当需要记录设备用量或对设备用量进行管控,需要填写该参数,否则,无法对设备进行用量管控,用量统计页面对应的自定义 ID 将显示为 N/A。
device_id 和 custom_consumer 建议选择其中一个即可。
custom_consumer 参数用于设备用量管控,与对话等 API 传入的 user_id 无关user_id 主要用于上下文、数据库隔离等场景。
出于数据隐私及信息安全等方面的考虑,不建议使用业务系统中定义的用户敏感标识(如手机号等)作为 custom_consumer 的值。
Payload 示例如下:
{
"iss": "310000000002", // OAuth 应用的 ID
"aud": "api.coze.cn", // 扣子 API 的 Endpoint
"iat": 1516239022, // JWT 开始生效的时间,秒级时间戳
"exp": 1516259022, // JWT 过期时间,秒级时间戳
"jti": "fhjashjgkhalskj", // 随机字符串,防止重放攻击
"session_name": "user_2222", //用户在业务侧的 UID
"session_context": {
"device_info": {
"device_id": "1234567890" // IoT 等硬件设备的唯一标识 ID
}
}
}
示例代码
你可以直接参考以下示例代码签署 JWT。
# You must run `pip install PyJWT cryptography` to install the PyJWT and the cryptography packages in order to use this script.
#!/usr/bin/env python3
import sys
import time
import uuid
import jwt
# 替换为你的实际 Coze App 私钥
signing_key = '''
-----BEGIN PRIVATE KEY-----
xxxxxxxxxxxxxxxxxx
-----END PRIVATE KEY-----
'''
payload = {
'iat': int(time.time()),
'exp': int(time.time()) + 600,
"jti": str(uuid.uuid4()),
'aud': 'api.coze.cn',
'iss': '1127900106117' # 替换为你的实际 Coze App ID
}
headers = {
'kid': '_v0VjcMlLdQc3tRTD3jC5Xz29TUnKQOhtuD5k-gpyf4' # 替换为你的实际 Coze App 公钥指纹
}
# Create JWT with headers
encoded_jwt = jwt.encode(payload, signing_key, algorithm='RS256', headers=headers)
print(f"JWT: {encoded_jwt}")
最终生成的 JWT 示例如下:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InZZd2ZsdFR1OWZBbWtwWFhSdnR5UmREc3RONVMzZWNFcDFqVzB6dVQyRE****.eyJpc3MiOiIzMTAwMDAwMDAwMDIiLCJhdWQiOiJhcGkuY296ZS5jb20iLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTkxNjI1OTAyMiwianRpIjoiZmhqaGFsc2tqZmFkc2pld3F****.CuoiCCF-nHFyGmu2EKlwFoyd3uDyKQ3Drc1CrXQyMVySTzZlZd2M7zKWsziB3AktwbUZiRJlQ1HbghR05CW2YRHwKL4-dlJ4koR3onU7iQAO5DkPCaIxbAuTsQobtCAdkkZTg8gav9EnN1QN_1xq0w8BzuuhS7wCeY8UbaskkTK9GnO4eU9tEINmVw-2CrfB-kNbEHlEDwXfcrb4YPpkw3GhmuPShenNLObfSWS0CqIyakXL8qD5AgXLoB-SejAsRdzloSUInNXENJHfSVMkThxRhJy7yEjX3BmculC54fMKENRfLElBqwJyLLUjeRHsYnaru2ca4W8_yaPJ7F****
3 获取访问令牌
应用程序调用 通过 JWT 获取 Oauth Access Token API ,请求 Header 中携带 JWT扣子服务端会在响应中通过 access_token 字段返回访问令牌。
请求示例如下:
curl --location --request POST 'https://api.coze.cn/api/permission/oauth2/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InZZd2ZsdFR1OWZBbWtwWFhSdnR5UmREc3RONVMzZWNFcDFqVzB6dVQyRE****.eyJpc3MiOiIzMTAwMDAwMDAwMDIiLCJhdWQiOiJhcGkuY296ZS5jb20iLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTkxNjI1OTAyMiwianRpIjoiZmhqaGFsc2tqZmFkc2pld3F****.CuoiCCF-nHFyGmu2EKlwFoyd3uDyKQ3Drc1CrXQyMVySTzZlZd2M7zKWsziB3AktwbUZiRJlQ1HbghR05CW2YRHwKL4-dlJ4koR3onU7iQAO5DkPCaIxbAuTsQobtCAdkkZTg8gav9EnN1QN_1xq0w8BzuuhS7wCeY8UbaskkTK9GnO4eU9tEINmVw-2CrfB-kNbEHlEDwXfcrb4YPpkw3GhmuPShenNLObfSWS0CqIyakXL8qD5AgXLoB-SejAsRdzloSUInNXENJHfSVMkThxRhJy7yEjX3BmculC54fMKENRfLElBqwJyLLUjeRHsYnaru2ca4W8_yaPJ7F****' \
--data '{
"duration_seconds": 86399,
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer"
}'
返回示例如下:
{
"access_token": "czs_RQOhsc7vmUzK4bNgb7hn4wqOgRBYAO6xvpFHNbnl6RiQJX3cSXSguIhFDzgy****",
"expires_in": 1721135859
}