外观
登录流程
2026-04-01
本文介绍 nebula-auth 的完整登录流程,包括验证码获取、账密登录、Token 刷新、登出,以及当前用户信息查询。
目录
一、登录时序图
用户 前端 nebula-auth
│ │ │
│ 点击登录页 │ │
│───────────────────────>│ │
│ │ GET /auth/captcha │
│ │─────────────────────────────>│
│ │ { captchaId, captchaImage } │
│ │<─────────────────────────────│
│ 展示验证码 │ │
│<───────────────────────│ │
│ │ │
│ 输入账号/密码/验证码 │ │
│───────────────────────>│ │
│ │ [可选] GET /auth/public-key │
│ │─────────────────────────────>│
│ │ { publicKey } │
│ │<─────────────────────────────│
│ │ RSA 加密密码 │
│ │ POST /auth/login │
│ │─────────────────────────────>│
│ │ { accessToken, refreshToken }│
│ │<─────────────────────────────│
│ 登录成功,进入系统 │ │
│<───────────────────────│ │二、获取验证码
在展示登录页时调用,获取验证码图片和对应的 ID。
接口: GET /auth/captcha
是否需要认证: 否
响应:
{
"code": 0,
"data": {
"captchaId": "550e8400-e29b-41d4-a716-446655440000",
"captchaImage": "data:image/png;base64,..."
}
}| 字段 | 说明 |
|---|---|
captchaId | 验证码 ID,提交登录时需带上 |
captchaImage | Base64 编码的验证码图片(数学题或图形) |
若服务端配置
captcha.enabled: false,该接口仍可调用但返回空图片,登录时captchaId和captchaCode传空即可。
三、获取 RSA 公钥(密码加密)
若服务端开启了 RSA 密码加密(login.rsa-enabled: true),前端需要先获取公钥,在客户端用公钥加密密码后再提交。
接口: GET /auth/public-key
是否需要认证: 否
响应:
{
"code": 0,
"data": {
"publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
}
}前端加密示例(JavaScript):
import JSEncrypt from 'jsencrypt'
const encrypt = new JSEncrypt()
encrypt.setPublicKey(publicKey)
const encryptedPassword = encrypt.encrypt(rawPassword)
// 提交登录时 password 字段传加密后的值若
login.rsa-enabled: false,密码明文传输(仅用于开发环境),生产环境必须开启。
四、账密登录
接口: POST /auth/login
是否需要认证: 否
请求体:
{
"username": "admin",
"password": "加密后的密码(或明文,取决于 rsa-enabled 配置)",
"captchaId": "550e8400-e29b-41d4-a716-446655440000",
"captchaCode": "7",
"loginDevice": "WEB"
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
username | String | ✅ | 登录账号 |
password | String | ✅ | 密码(rsa-enabled=true 时须用公钥加密) |
captchaId | String | 验证码开启时必填 | 验证码 ID |
captchaCode | String | 验证码开启时必填 | 用户输入的验证码答案 |
loginDevice | String | 否 | 登录设备类型(WEB / APP / MINI_PROGRAM 等) |
成功响应:
{
"code": 0,
"data": {
"accessToken": "eyJhbGciOiJSUzI1NiJ9...",
"refreshToken": "eyJhbGciOiJSUzI1NiJ9...",
"accessTokenExpireAt": "2026-04-01T12:00:00",
"refreshTokenExpireAt": "2026-04-15T10:00:00",
"expiresIn": 7200,
"tokenType": "Bearer"
}
}| 字段 | 说明 |
|---|---|
accessToken | 访问令牌,请求业务接口时在 Header 中携带 |
refreshToken | 刷新令牌,用于续签 AccessToken |
accessTokenExpireAt | AccessToken 过期时间 |
refreshTokenExpireAt | RefreshToken 过期时间 |
expiresIn | AccessToken 有效秒数 |
tokenType | 固定为 Bearer |
前端使用 Token:
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...常见错误响应:
| 场景 | code | message |
|---|---|---|
| 验证码错误 | 400002 | 验证码错误 |
| 验证码已过期 | 400002 | 验证码已过期,请刷新 |
| 账号不存在 | 400002 | 账号或密码错误 |
| 密码错误 | 400002 | 账号或密码错误(第 N 次,还剩 M 次机会) |
| 账号已锁定 | 400002 | 账号已被锁定,请 30 分钟后再试 |
| 账号已禁用 | 400002 | 账号已被禁用,请联系管理员 |
五、刷新 Token
AccessToken 到期后,用 RefreshToken 换取新的 Token 对。
接口: POST /auth/refresh
是否需要认证: 否
请求体:
{
"refreshToken": "eyJhbGciOiJSUzI1NiJ9..."
}成功响应: 与登录响应相同(返回新的 accessToken 和 refreshToken)
说明: RefreshToken 刷新后,原 RefreshToken 失效。前端应及时保存新的 Token 对。
若 RefreshToken 也已过期,需重新登录。
六、登出
接口: POST /auth/logout
是否需要认证: ✅ 需要
调用后,当前 AccessToken 和 RefreshToken 立即失效。
请求头:
Authorization: Bearer {accessToken}响应:
{
"code": 0,
"message": "操作成功"
}七、查询当前用户信息
获取当前登录用户的基本信息(用于前端展示用户名、头像等)。
接口: GET /auth/me
是否需要认证: ✅ 需要
响应:
{
"code": 0,
"data": {
"userId": 10001,
"username": "admin",
"nickname": "系统管理员",
"tenantId": 1001,
"tenantCode": "TENANT_001",
"roles": ["ROLE_ADMIN"],
"permissions": ["system:user:query", "system:user:create"]
}
}八、查询 Token 状态
查询当前 Token 的有效状态(前端可用于判断是否需要刷新)。
接口: GET /auth/token/status
是否需要认证: ✅ 需要
响应:
{
"code": 0,
"data": {
"tokenId": "abc123",
"accessTokenExpireAt": "2026-04-01T12:00:00",
"accessTokenRemainingSeconds": 3600,
"refreshTokenRemainingSeconds": 86400,
"onlineSessions": 2
}
}九、强制登出
管理员可以强制让某个用户的所有会话失效。
强制登出当前登录用户的所有会话:
POST /auth/sessions/force-logout
Authorization: Bearer {accessToken}强制登出指定用户(需要 ROLE_ADMIN 角色):
POST /auth/sessions/force-logout/{userId}
Authorization: Bearer {adminAccessToken}十、Token 说明
AccessToken 携带方式
所有需要认证的业务接口都通过 HTTP Header 携带 AccessToken:
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...Token 有效期说明
- AccessToken: 短期有效(通常 2 小时),到期后需用 RefreshToken 续签
- RefreshToken: 长期有效(通常 14 天),到期后需重新登录
JWT Payload 中的自定义字段
nebula-auth 在 JWT Token 中额外注入了以下 Claim:
| Claim | 说明 |
|---|---|
tenant_code | 当前租户编码(有租户上下文时注入) |
业务服务收到请求时,框架自动解析 JWT 并将信息写入 SecurityContextHolder 和 TenantContextHolder,业务代码可直接使用。
