# routers/auth.py 接口测试文档 ## 文件功能概述 该文件提供用户认证相关接口,包括本地用户登录、用户注册、获取用户信息。使用 bcrypt 进行密码加密,JWT 进行 Token 签发与验证。 --- ## 接口列表 ### 1. POST `/apiv1/auth/local_login` — 本地用户登录 **功能说明:** 用户通过用户名和密码进行本地登录,验证成功后返回 JWT Token 和用户基本信息。 **是否需要认证:** 否(白名单路径) **请求方式:** POST **请求路径:** `/apiv1/auth/local_login` **请求头:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | Content-Type | string | 是 | `application/json` | **请求体(JSON):** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | username | string | 是 | 用户名,不能为空 | | password | string | 是 | 密码,不能为空 | **测试用例:** #### 用例 1:正常登录成功 ```json // 请求 POST /apiv1/auth/local_login Content-Type: application/json { "username": "testuser", "password": "Test@123456" } // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "登录成功", "token": "", "userInfo": { "id": 1, "username": "testuser", "nickname": "测试用户", "role": "user", "email": "" } } ``` #### 用例 2:用户名或密码为空 ```json // 请求 POST /apiv1/auth/local_login Content-Type: application/json { "username": "", "password": "" } // 预期响应 (HTTP 200, 业务码 400) { "statusCode": 400, "msg": "用户名和密码不能为空" } ``` #### 用例 3:用户名不存在 ```json // 请求 POST /apiv1/auth/local_login Content-Type: application/json { "username": "nonexistent_user", "password": "anypassword" } // 预期响应 (HTTP 200, 业务码 401) { "statusCode": 401, "msg": "用户名或密码错误" } ``` #### 用例 4:密码错误 ```json // 请求 POST /apiv1/auth/local_login Content-Type: application/json { "username": "testuser", "password": "wrongpassword" } // 预期响应 (HTTP 200, 业务码 401) { "statusCode": 401, "msg": "用户名或密码错误" } ``` #### 用例 5:用户已被禁用(status != 1) ```json // 请求 POST /apiv1/auth/local_login Content-Type: application/json { "username": "disableduser", "password": "Test@123456" } // 预期响应 (HTTP 200, 业务码 403) { "statusCode": 403, "msg": "用户已被禁用" } ``` #### 用例 6:请求体不是合法 JSON ``` // 请求 POST /apiv1/auth/local_login Content-Type: application/json this is not json // 预期响应 (HTTP 200, 业务码 400) { "statusCode": 400, "msg": "请求参数解析失败" } ``` --- ### 2. POST `/apiv1/auth/register` — 用户注册 **功能说明:** 创建新用户账号,使用 bcrypt 加密密码存储。支持 `account` 和 `username` 两种字段名传入(向后兼容)。 **是否需要认证:** 否(白名单路径) **请求方式:** POST **请求路径:** `/apiv1/auth/register` **请求头:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | Content-Type | string | 是 | `application/json` | **请求体(JSON):** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | account / username | string | 是 | 账号名(两个字段二选一,`account` 优先) | | password | string | 是 | 密码 | | name | string | 否 | 昵称,不传则默认使用 account 值 | **测试用例:** #### 用例 1:正常注册成功 ```json // 请求 POST /apiv1/auth/register Content-Type: application/json { "account": "newuser", "password": "NewPass@123", "name": "新用户" } // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "注册成功", "data": { "user_id": 2, "account": "newuser" } } ``` #### 用例 2:使用 username 字段注册(兼容性) ```json // 请求 POST /apiv1/auth/register Content-Type: application/json { "username": "newuser2", "password": "NewPass@123" } // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "注册成功", "data": { "user_id": 3, "account": "newuser2" } } ``` #### 用例 3:账号或密码为空 ```json // 请求 POST /apiv1/auth/register Content-Type: application/json { "account": "", "password": "" } // 预期响应 (HTTP 200, 业务码 400) { "statusCode": 400, "msg": "账号和密码不能为空" } ``` #### 用例 4:账号已存在 ```json // 请求 POST /apiv1/auth/register Content-Type: application/json { "account": "testuser", "password": "Test@123456" } // 预期响应 (HTTP 200, 业务码 400) { "statusCode": 400, "msg": "账号已存在" } ``` #### 用例 5:请求体不是合法 JSON ``` // 请求 POST /apiv1/auth/register Content-Type: application/json not json // 预期响应 (HTTP 200, 业务码 400) { "statusCode": 400, "msg": "请求参数解析失败" } ``` --- ### 3. GET `/apiv1/auth/user/info` — 获取用户信息 **功能说明:** 获取当前登录用户的详细信息。需要认证。对于本地用户返回本地表数据,对于外部用户返回 UserData 表数据。 **是否需要认证:** 是 **请求方式:** GET **请求路径:** `/apiv1/auth/user/info` **请求头:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | token | string | 是(二选一) | 认证 Token | | Authorization | string | 是(二选一) | `Bearer ` | **请求体:** 无 **测试用例:** #### 用例 1:正常获取本地用户信息 ```json // 请求 GET /apiv1/auth/user/info token: <有效的JWT Token> // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "success", "data": { "user_id": 1, "account": "testuser", "name": "测试用户", "points": 0, "created_at": 1700000000 } } ``` #### 用例 2:正常获取外部用户信息(本地用户表无记录时回退查询 UserData 表) ```json // 请求 GET /apiv1/auth/user/info Authorization: Bearer <有效的外部用户JWT Token> // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "success", "data": { "user_id": 100, "account": "external_account_id", "name": "外部用户", "points": 50, "created_at": 1700000000 } } ``` #### 用例 3:未提供 Token ```json // 请求 GET /apiv1/auth/user/info // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "未提供认证Token" } ``` > 注意:此响应由 main.py 中间件拦截返回,并非本接口内部逻辑。 #### 用例 4:Token 无效或已过期 ```json // 请求 GET /apiv1/auth/user/info token: invalid_token_string // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "Token验证失败" } ``` > 注意:此响应由 main.py 中间件拦截返回。 #### 用例 5:用户数据不存在(外部用户在 UserData 表中无记录) ```json // 请求 GET /apiv1/auth/user/info token: // 预期响应 (HTTP 200, 业务码 404) { "statusCode": 404, "msg": "用户数据不存在" } ``` --- ## 依赖说明 | 依赖项 | 说明 | |--------|------| | `database.SessionLocal` | SQLAlchemy 数据库会话 | | `models.total.User` | 本地用户模型(字段:id, username, password, nickname, role, email, status, is_deleted, created_at) | | `models.user_data.UserData` | 外部用户数据模型(字段:id, accountID, name, points, created_at) | | `bcrypt` | 密码哈希加密 | | `jwt` (PyJWT) | JWT Token 生成 | | `utils.logger.logger` | 日志记录 | ## JWT Token 信息 - 签发密钥:`shudao-local-jwt-secret-2024` - 算法:HS256 - 有效期:24 小时 - Payload 包含字段:`user_id`, `username`, `role`, `source`("local"), `exp`, `iat`