# 前端安全升级接入指南 为了提高安全性,后端鉴权机制已升级为 **Token + Device Binding + Session Enforcement**。 **⚠️ 核心变更:所有身份验证相关的接口现在都强制要求携带 `device_id`。** 前端必须配合进行以下改动,否则接口将返回 `422 Unprocessable Entity` (参数缺失) 或 `401 Unauthorized` (设备不匹配)。 --- ## 🛠️ 接口改造清单 请检查并修改以下所有接口的调用参数: ### 1. 登录接口 (Login) * **URL**: `/api/v1/auth/login` * **变更**: 新增必填字段 `device_id`。 * **说明**: 之前的文档描述有误,登录接口**必须**传此参数,否则无法建立会话。 **修改后示例:** ```typescript const loginData = { username: "user1", password: "pwd", device_id: getDeviceId() // ✅ 必传 }; ``` ### 2. 注册接口 (Register) * **URL**: `/api/v1/auth/register` * **变更**: 新增必填字段 `device_id`。 * **说明**: 注册成功后会自动登录,因此必须绑定当前设备。 **修改后示例:** ```typescript const registerData = { username: "user1", password: "pwd", confirm_password: "pwd", device_id: getDeviceId() // ✅ 必传 }; ``` ### 3. 登出接口 (Logout) * **URL**: `/api/v1/auth/logout` * **变更**: 新增必填字段 `device_id`。 * **说明**: 用于精准注销当前设备的会话,而不影响用户在其他设备上的登录状态。 **修改后示例:** ```typescript const logoutData = { username: "user1", device_id: getDeviceId() // ✅ 必传 }; ``` ### 4. 心跳保活接口 (Heartbeat) * **URL**: `/api/v1/auth/heartbeat` * **变更**: 新增必填字段 `device_id`。 * **说明**: 用于维持当前设备 Session 的活跃状态。 **修改后示例:** ```typescript const heartbeatData = { username: "user1", device_id: getDeviceId() // ✅ 必传 }; ``` ### 5. 许可证验证接口 (Verify) * **URL**: `/api/v1/auth/verify` * **变更**: 新增必填字段 `device_id`。 * **说明**: 后端会校验 Token 中的设备 ID 是否与参数中的设备 ID 一致,且 Session 是否活跃。 **修改后示例:** ```typescript const verifyData = { username: "user1", timestamp: Date.now(), device_id: getDeviceId() // ✅ 必传 }; ``` --- ## 🚨 统一错误处理 (Interceptor) 由于新的强校验机制,`401 Unauthorized` 可能会在任何接口出现(不仅仅是 Token 过期,也可能是被踢下线)。 前端拦截器需要统一处理 `401`,强制跳转到登录页。 **Axios 拦截器示例:** ```typescript axios.interceptors.response.use( (response) => response, (error) => { if (error.response && error.response.status === 401) { // 1. 清除本地 Token localStorage.removeItem('access_token'); // 2. 提示用户 const msg = error.response.data.detail || '登录已失效,请重新登录'; // Message.error(msg); // Arco Design / Element UI console.error(msg); // 3. 跳转登录页 // 如果是 Shell 环境,跳转到 Shell 登录 if (window.location.hash.indexOf('/login') === -1) { window.location.href = '/shell/index.html#/login'; } } return Promise.reject(error); } ); ``` --- ## 💡 关于 device_id 的说明 `device_id` 是用于标识客户端设备的唯一字符串。 * **生成方式**:建议在应用启动时检查 `LocalStorage`,如果没有则生成一个 UUID 并存入;如果有则直接读取。 * **作用**:用于区分不同的客户端实例,实现单设备登录限制(互踢功能)。 * **持久化**:必须确保存储在浏览器/CEP 环境的持久化存储中(如 `localStorage`),避免刷新页面后变化。