认证授权
ChainlessChain API采用基于JWT的认证机制,确保API调用的安全性。
认证方式
1. API Token认证(推荐)
适用于服务端调用。
获取API Token
厂家管理系统:
系统设置 → API管理 → 创建Token
Token名称: 生产环境API
权限范围:
☑ 设备管理
☑ APP版本管理
□ 用户管理
□ 系统管理
有效期:
○ 30天
○ 90天
● 1年
○ 永久
创建Token →
复制保存: ccapi_1234567890abcdef...使用Token
GET /api/v1/devices
Authorization: Bearer ccapi_1234567890abcdef...2. OAuth 2.0
适用于第三方应用集成。
授权码流程
1. 重定向用户到授权页面
GET https://auth.chainlesschain.com/oauth/authorize
?client_id={client_id}
&redirect_uri={redirect_uri}
&response_type=code
&scope=device:read device:write
&state={random_state}
2. 用户授权后获取授权码
→ {redirect_uri}?code={authorization_code}&state={random_state}
3. 使用授权码换取访问令牌
POST https://auth.chainlesschain.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code={authorization_code}
&client_id={client_id}
&client_secret={client_secret}
&redirect_uri={redirect_uri}
响应:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"scope": "device:read device:write"
}
4. 使用访问令牌调用API
GET /api/v1/devices
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...3. 用户名密码
仅用于内部系统或测试环境。
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "********"
}响应:
{
"code": 0,
"message": "登录成功",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 3600,
"tokenType": "Bearer"
}
}JWT Token结构
Header
{
"alg": "HS256",
"typ": "JWT"
}Payload
{
"sub": "user123",
"iat": 1704096000,
"exp": 1704099600,
"scope": ["device:read", "device:write"],
"iss": "chainlesschain.com",
"aud": "api.chainlesschain.com"
}Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)权限范围(Scopes)
设备管理
| Scope | 说明 | 权限 |
|---|---|---|
| device:read | 读取设备信息 | 查看设备列表、详情 |
| device:write | 写入设备信息 | 注册、激活、更新设备 |
| device:delete | 删除设备 | 删除、报废设备 |
| device:manage | 管理设备 | 所有设备操作权限 |
APP版本管理
| Scope | 说明 | 权限 |
|---|---|---|
| app:read | 读取APP版本 | 查看版本列表、详情 |
| app:write | 上传APP版本 | 上传新版本 |
| app:publish | 发布APP版本 | 发布版本到生产环境 |
| app:manage | 管理APP版本 | 所有版本操作权限 |
用户管理
| Scope | 说明 | 权限 |
|---|---|---|
| user:read | 读取用户信息 | 查看用户列表、详情 |
| user:write | 写入用户信息 | 创建、更新用户 |
| user:delete | 删除用户 | 删除用户账户 |
| user:manage | 管理用户 | 所有用户操作权限 |
系统管理
| Scope | 说明 | 权限 |
|---|---|---|
| system:read | 读取系统信息 | 查看系统配置、日志 |
| system:write | 写入系统配置 | 更新系统配置 |
| system:manage | 管理系统 | 所有系统操作权限 |
Token刷新
刷新访问令牌
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refreshToken": "eyJhbGciOiJIUzI1NiIs..."
}响应:
{
"code": 0,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...", // 新的访问令牌
"refreshToken": "eyJhbGciOiJIUzI1NiIs...", // 新的刷新令牌
"expiresIn": 3600
}
}自动刷新机制
class APIClient {
private accessToken: string;
private refreshToken: string;
private expiresAt: number;
async request(url: string, options: RequestInit) {
// 检查token是否即将过期(提前5分钟刷新)
if (Date.now() + 300000 >= this.expiresAt) {
await this.refreshAccessToken();
}
return fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${this.accessToken}`,
},
});
}
private async refreshAccessToken() {
const response = await fetch("/api/v1/auth/refresh", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ refreshToken: this.refreshToken }),
});
const data = await response.json();
this.accessToken = data.data.accessToken;
this.refreshToken = data.data.refreshToken;
this.expiresAt = Date.now() + data.data.expiresIn * 1000;
}
}错误处理
认证错误码
| 错误码 | HTTP状态码 | 说明 | 解决方法 |
|---|---|---|---|
| 401001 | 401 | Token缺失 | 提供Authorization头 |
| 401002 | 401 | Token无效 | 使用有效的Token |
| 401003 | 401 | Token过期 | 刷新Token |
| 401004 | 401 | 签名错误 | 检查Token完整性 |
| 403001 | 403 | 权限不足 | 申请相应权限 |
| 403002 | 403 | Scope不足 | 扩展Scope范围 |
| 429001 | 429 | 请求过于频繁 | 降低请求频率 |
错误响应示例
{
"code": 401003,
"message": "Token已过期",
"error": "token_expired",
"timestamp": "2024-01-15T10:30:00Z",
"path": "/api/v1/devices"
}速率限制
限制策略
| Token类型 | 限制 | 时间窗口 |
|---|---|---|
| API Token | 1000次 | 1小时 |
| OAuth Token | 500次 | 1小时 |
| 用户登录 | 100次 | 1小时 |
响应头
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1704099600超出限制
HTTP/1.1 429 Too Many Requests
Retry-After: 1800
{
"code": 429001,
"message": "请求过于频繁,请稍后再试",
"retryAfter": 1800
}安全最佳实践
1. Token安全
// ✅ 推荐:存储在环境变量
const apiToken = process.env.CHAINLESSCHAIN_API_TOKEN;
// ❌ 不推荐:硬编码在代码中
const apiToken = "ccapi_1234567890abcdef...";
// ✅ 推荐:使用HTTPS
const apiUrl = "https://api.chainlesschain.com";
// ❌ 不推荐:使用HTTP
const apiUrl = "http://api.chainlesschain.com";2. Token轮换
定期轮换API Token:
- 生产环境: 每90天
- 测试环境: 每30天
- 开发环境: 根据需要
设置提醒:
系统设置 → API管理 → Token过期提醒3. 最小权限原则
只申请必要的权限:
// ✅ 推荐:最小权限
scopes: ['device:read']
// ❌ 不推荐:过度权限
scopes: ['device:manage', 'user:manage', 'system:manage']4. IP白名单
系统设置 → API管理 → IP白名单
添加允许的IP:
- 192.168.1.100
- 10.0.0.0/24
- 2001:db8::/32
启用IP白名单验证示例代码
JavaScript/Node.js
const axios = require("axios");
const client = axios.create({
baseURL: "https://api.chainlesschain.com/api/v1",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
"Content-Type": "application/json",
},
});
// 带自动重试的请求
async function requestWithRetry(config, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await client(config);
} catch (error) {
if (error.response?.status === 401 && i < maxRetries - 1) {
// Token过期,刷新后重试
await refreshToken();
continue;
}
throw error;
}
}
}
// 使用示例
const devices = await requestWithRetry({ url: "/devices" });Python
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
class ChainlessChainAPI:
def __init__(self, api_token):
self.base_url = 'https://api.chainlesschain.com/api/v1'
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_token}',
'Content-Type': 'application/json'
})
# 配置自动重试
retry = Retry(
total=3,
backoff_factor=0.3,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
self.session.mount('https://', adapter)
def get_devices(self, page=1, size=20):
response = self.session.get(
f'{self.base_url}/devices',
params={'page': page, 'size': size}
)
response.raise_for_status()
return response.json()
# 使用示例
api = ChainlessChainAPI(os.getenv('API_TOKEN'))
devices = api.get_devices()测试工具
Postman配置
{
"info": {
"name": "ChainlessChain API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_token}}",
"type": "string"
}
]
},
"variable": [
{
"key": "base_url",
"value": "https://api.chainlesschain.com/api/v1"
},
{
"key": "api_token",
"value": "ccapi_1234567890abcdef..."
}
]
}cURL示例
# 获取设备列表
curl -X GET "https://api.chainlesschain.com/api/v1/devices?page=1&size=20" \
-H "Authorization: Bearer ccapi_1234567890abcdef..." \
-H "Content-Type: application/json"
# 注册设备
curl -X POST "https://api.chainlesschain.com/api/v1/devices/register" \
-H "Authorization: Bearer ccapi_1234567890abcdef..." \
-H "Content-Type: application/json" \
-d '{
"deviceType": "U盾",
"model": "ePass3003",
"serialNumber": "UP2024010100001"
}'常见问题
Token在哪里获取?
登录厂家管理系统 → 系统设置 → API管理 → 创建Token
Token可以分享吗?
不可以。Token相当于密码,不应分享给他人。每个应用/服务应使用独立的Token。
如何撤销Token?
系统设置 → API管理 → Token列表 → 点击"撤销"
忘记Token怎么办?
Token不可找回,只能重新生成。建议妥善保管。
附录:规范章节补全(v5.0.3.108)
为对齐项目用户文档标准结构,下列章节补齐若干未在正文中单独列出的视角。已在正文覆盖的章节在此段仅作简述并标注
见上文指引。
1. 概述
见正文「认证方式」。认证授权模块提供 API Token(推荐)/ OAuth 2.0 / 用户名密码三种认证,配合 JWT 结构、权限 Scope、Token 刷新与速率限制。
2. 核心特性
- 三种认证:API Token / OAuth 2.0(授权码 + PKCE)/ 用户名密码
- JWT 结构(Header / Payload / Signature)
- 权限 Scope(设备 / APP / 用户 / 系统管理)
- Token 刷新 + 自动刷新机制
3. 系统架构
客户端 ──认证──► 获取 Token(API Token / OAuth / 登录)
▼
请求携带 Authorization: Bearer <JWT>
▼
后端校验签名 + 过期 + Scope(每请求)→ 放行 / 401 / 4034. 系统定位
所有 API 的统一认证授权关口,是 API 简介 的安全基座。
5. 核心功能
见正文:获取 / 使用 Token、OAuth 2.0 授权码流程、JWT 结构、Scope 体系、Token 刷新与自动刷新。
6. 技术架构
JWT(HS256/RS256)+ Bearer;OAuth 2.0 授权码 + PKCE;Scope 粒度鉴权;Token 经 refresh token 续期。
7. 系统特点
- API Token 一应用一 Token,不可分享
- Scope 最小授权
- Token 不可找回,只能重新生成
8. 应用场景
服务端集成用 API Token;第三方应用用 OAuth 2.0;用户登录用密码换 JWT。
9. 竞品对比
| 维度 | 本模块 | 仅密码认证 |
|---|---|---|
| API Token | ✅ | ❌ |
| OAuth 2.0 | ✅ PKCE | ❌ |
| Scope 粒度 | ✅ | ❌ |
| Token 轮换 | ✅ | ⚠️ |
10. 配置参考
见正文:Authorization: Bearer <token>;OAuth 授权码流程参数;Scope 列表;IP 白名单(见正文「安全最佳实践」)。
11. 性能指标
见正文「速率限制」:API Token 1000 次/小时、OAuth Token 500 次/小时、用户登录 100 次/小时;超限 429 + Retry-After + X-RateLimit-* 头。
12. 测试覆盖
见正文「测试工具」:Postman 配置、cURL 示例;签名校验 / 过期 / Scope / 刷新由后端集成测试覆盖。
13. 安全考虑
见正文「安全最佳实践」:Token 安全存储、Token 轮换、最小权限 Scope、IP 白名单。认证错误码 401001–429001(见正文「认证错误码」)。
14. 故障排除
见正文「认证错误码」表:
| 错误码 | 处理 |
|---|---|
| 401001 / 401002 | 提供 / 更换有效 Token |
| 401003 | 刷新 Token |
| 401004 | 检查 Token 完整性 |
| 403001 / 403002 | 申请权限 / 扩展 Scope |
| 429001 | 降低请求频率(看 Retry-After) |
15. 关键文件
| 资源 | 说明 |
|---|---|
/api/auth/* | 登录 / Token / 刷新接口 |
| Scope 定义 | 设备 / APP / 用户 / 系统管理 |
| Swagger UI | http://localhost:8080/api/swagger-ui.html |
16. 使用示例
见正文「示例代码」(JS/Node.js、Python)与「测试工具 — cURL示例」。
