--- title: 登录与鉴权 description: 登录、凭证携带、会话顶替与登录日志 pageClass: g3-api --- # 登录与鉴权 除 `/auth/login` 外,**所有接口都需要携带凭证**。 ## `POST` `/auth/login` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `orgid` | string | 是 | 机构码,决定登录到**哪个机构的库** | | `userid` | string | 是 | 用户账号(`b_user.b_id`) | | `password` | string | 是 | 密码 | ```bash curl -X POST http://localhost:8088/api/auth/login \ -H 'Content-Type: application/json' \ -d '{"orgid":"G3HD","userid":"g3soft","password":"******"}' ``` ```json { "code": 0, "message": "操作成功", "data": { "token": "eyJhbGciOiJIUzI1NiJ9...", "orgid": "G3HD", "user": { "id": "g3soft", "account": "g3soft", "name": "G3Soft" } } } ``` ```json { "code": 401, "message": "机构码、账号或密码错误", "data": null } ``` **几点要注意**: - **机构码会归一化**:去掉首尾空白并转大写,所以传 `g3hd` 与 `G3HD` 等价。 - **机构码决定数据源**:登录时按机构码加载该机构的数据库配置;机构码不存在或配置缺失会失败。 - **「账号不存在」与「密码错误」对外是同一个提示**(`机构码、账号或密码错误`),不区分——避免被用来探测账号是否存在。但**登录日志里会分别记录**真实原因,便于排查。 - **`user.id` 与 `user.account` 目前是同一个值**(字符串业务键方案:`b_user.b_id` 即账号本身)。 - 用户编码与机构码都会写进 JWT,后续请求据此路由数据源与判定权限。 ## 携带凭证 所有后续请求在请求头带 Bearer token: ```bash curl -X POST http://localhost:8088/api/data/page \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...' \ -d '{"view_name":"v_b_othercompany","order_by":"b_id ASC"}' ``` | 场景 | 结果 | |---|---| | 缺少或格式不对的 `Authorization` | `401` | | token 无效 / 过期 / 签名不符 | `401` | | token 有效但**会话已被顶替** | `40101` | | `OPTIONS` 预检请求 | **放行**(不校验) | | `/auth/login` | **放行**(唯一不需要凭证的业务接口) | > **HTTP 状态码始终是 200**,鉴权失败靠响应体的 `code`(`401` / `40101`)判断。 > 不要用 HTTP 状态码或 axios 的错误拦截分支处理鉴权失败。 ## 会话与顶替 服务端维护**活动会话表**,同一个「机构 + 账号」只保留一个有效会话: ```text 登录 → 生成 sessionId → 登记为活动会话 再次登录同一账号 → 旧会话被顶替 旧 token 继续用 → 返回 40101(账号已在其他设备登录) ``` **前端处理**:拿到 `401` 或 `40101` 都应**清 token、回登录页**。`40101` 建议给一句「账号已在其他设备登录」,比笼统的「登录已失效」更有助于用户理解。 > 会话是**内存态**:服务重启后全部失效,用户需重新登录。 ## 登录日志 每次登录尝试都会记录,含成功与失败: | 记录内容 | 说明 | |---|---| | 机构码、用户账号 | 尝试登录的身份 | | 成功 / 失败、失败原因 | 「账号不存在」/「密码错误」 | | 会话 ID | 登录成功时 | | 客户端信息 | 浏览器、操作系统、设备类型 | | IP 与归属地 | 来源地址解析 | 查询入口:`v_s_log_login` 视图(走通用查询接口)。日志表本身**不需要登录权限之外的特殊授权**,但建议只给管理员开放。 ## 相关配置 | 配置项 | 说明 | |---|---| | `erp.auth.jwt-secret` | 签名密钥,**生产必须改**(默认值仅用于开发) | | `erp.auth.jwt-expiration` | token 有效期,默认 `24h` | | `erp.database.config-dir` | 机构数据库配置目录,登录时按机构码在此查找 | ## 常见错误 | 场景 | code | 说明 | |---|---|---| | 机构码为空 | `1000` | 「机构码不能为空」 | | 用户 ID 为空 | `1000` | 「用户ID不能为空」 | | 机构码、账号或密码错误 | `401` | 三者统一提示 | | 机构码在配置目录里不存在 | `401` | 加载机构配置失败时按机构码错误处理 | | 未带凭证访问其他接口 | `401` | —— | | 会话被顶替 | `40101` | 需重新登录 |