Skip to content

认证授权

ChainlessChain API采用基于JWT的认证机制,确保API调用的安全性。

认证方式

1. API Token认证(推荐)

适用于服务端调用。

获取API Token

厂家管理系统:
系统设置 → API管理 → 创建Token

Token名称: 生产环境API
权限范围:
☑ 设备管理
☑ APP版本管理
□ 用户管理
□ 系统管理

有效期:
○ 30天
○ 90天
● 1年
○ 永久

创建Token →
复制保存: ccapi_1234567890abcdef...

使用Token

http
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. 用户名密码

仅用于内部系统或测试环境。

http
POST /api/v1/auth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "********"
}

响应:

json
{
  "code": 0,
  "message": "登录成功",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
    "expiresIn": 3600,
    "tokenType": "Bearer"
  }
}

JWT Token结构

json
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

json
{
  "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刷新

刷新访问令牌

http
POST /api/v1/auth/refresh
Content-Type: application/json

{
  "refreshToken": "eyJhbGciOiJIUzI1NiIs..."
}

响应:

json
{
  "code": 0,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs...", // 新的访问令牌
    "refreshToken": "eyJhbGciOiJIUzI1NiIs...", // 新的刷新令牌
    "expiresIn": 3600
  }
}

自动刷新机制

typescript
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状态码说明解决方法
401001401Token缺失提供Authorization头
401002401Token无效使用有效的Token
401003401Token过期刷新Token
401004401签名错误检查Token完整性
403001403权限不足申请相应权限
403002403Scope不足扩展Scope范围
429001429请求过于频繁降低请求频率

错误响应示例

json
{
  "code": 401003,
  "message": "Token已过期",
  "error": "token_expired",
  "timestamp": "2024-01-15T10:30:00Z",
  "path": "/api/v1/devices"
}

速率限制

限制策略

Token类型限制时间窗口
API Token1000次1小时
OAuth Token500次1小时
用户登录100次1小时

响应头

http
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1704099600

超出限制

http
HTTP/1.1 429 Too Many Requests
Retry-After: 1800

{
  "code": 429001,
  "message": "请求过于频繁,请稍后再试",
  "retryAfter": 1800
}

安全最佳实践

1. Token安全

typescript
// ✅ 推荐:存储在环境变量
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

javascript
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

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配置

json
{
  "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示例

bash
# 获取设备列表
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 / 403

4. 系统定位

所有 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 UIhttp://localhost:8080/api/swagger-ui.html

16. 使用示例

见正文「示例代码」(JS/Node.js、Python)与「测试工具 — cURL示例」。

17. 相关文档

基于 MIT 许可发布