场景题
登录认证和权限校验怎么实现?
Spring Security + JWT + Redis为例,登录时核实身份,之后每次请求检查登录状态,访问具体接口时再检查权限。
登录
1. 用户输入账号、密码、验证码
前端把它们提交给后端的 /login 接口。
2. 后端检查账号密码
先校验验证码,再通过 Spring Security 查询数据库中的用户,检查账号状态,并校验密码。
验证成功后,得到一个 LoginUser,里面包含用户信息和权限。
3. 把登录信息存入 Redis
后端生成一个随机 UUID,作为这次登录的唯一标识,例如 abc123。
Redis 中保存的内容可以理解成:
1 | login_tokens:abc123 → LoginUser(用户信息、权限等) |
同时设置过期时间。
4. 生成 JWT,返回给前端
后端把 abc123 这个登录标识放进 JWT,再签名,返回给前端。
注意区分:
- JWT:前端拿着的登录凭证。
- UUID:JWT 里面的登录标识,用来查 Redis。
- LoginUser:Redis 中保存的实际登录信息。
5. 后续请求,前端携带 JWT
比如查询用户列表时,请求头带上:
1 | Authorization: Bearer JWT字符串 |
后端过滤器会:
1 | 校验 JWT 签名,取出 UUID |
如果 Redis 中的登录记录过期或被删除,即使前端还拿着 JWT,也不能继续以该身份访问。
总结:通过 Spring Security 校验账号密码。登录成功后,生成一个 UUID,将用户信息和权限存入 Redis,再把 UUID 放进 JWT 返回给前端。后续请求携带 JWT,后端过滤器验证并解析出 UUID,到 Redis 获取登录用户,再把认证信息放入 SecurityContext,供后续权限校验使用。退出登录时删除 Redis 中的登录信息。
权限校验
RBAC,也就是通过角色分配权限:
1 | 用户 → 角色 → 权限 |
后端加载用户权限后,可以通过注解控制接口或方法的访问:
1 | @PreAuthorize("hasAuthority('order:delete')") |
需要开启方法权限校验。用户已经登录,但没有对应权限,通常返回 403。
总结:RBAC 是基于角色的权限控制,通过用户关联角色、角色关联权限来授权。通常使用用户、角色、权限以及两张关联表实现。用户登录后,查询并合并其所有角色的权限,访问接口时,再检查当前用户是否具有接口要求的权限。
Java日志级别?
Spring Boot 项目中常见的是 SLF4J + Logback:
- SLF4J:提供统一的日志接口。
- Logback:实际负责输出日志。
1 | @Slf4j |
日志级别
| 级别 | 常见用途 |
|---|---|
TRACE |
非常细的执行过程 |
DEBUG |
调试信息,例如中间变量 |
INFO |
正常的关键业务事件,例如订单创建成功 |
WARN |
出现异常情况,但暂时还能继续处理 |
ERROR |
操作失败,需要关注和排查 |
