本文是「EduCore 教务系统实战系列」第 2 篇,介绍我如何使用 Spring Boot + JWT 实现多角色(管理员 / 教师 / 学生)无状态登录认证机制,附带流程图、完整思路与关键代码结构,适合中后台系统开发者参考。
🎯 实现目标
- ✅ 支持
ADMIN
/TEACHER
/STUDENT
三种角色登录; - ✅ 登录后返回 JWT Token,无需 Session;
- ✅ 通过前端携带 Token 实现鉴权访问;
- ✅ Token 中封装用户 ID、角色等核心信息;
- ✅ 登录认证逻辑通过策略模式解耦;
- ✅ 权限由 Spring Security 控制,支持细粒度接口权限拦截;
🔐 为什么选择 JWT + Spring Security?
对比项 | 原始方案(Session) | 当前方案(JWT + Security) |
---|---|---|
状态管理 | 服务器维护 Session | 客户端持有 Token,后端无状态 |
可扩展性 | 多端登录困难 | 可用于移动端、小程序、扫码登录等 |
灵活性 | 角色识别困难,易混乱 | 可在 Token 中封装角色、权限 |
安全控制 | 拦截器写死判断 | 使用 Spring Security 细粒度控制 |
📌 登录流程图
plaintext
[用户登录页面]
|
v
[输入账号/密码 + 角色]
|
v
[Controller 登录接口(/login)]
|
v
[LoginStrategyFactory 获取对应策略]
|
v
[xxxLoginStrategy 登录验证]
|
v
[登录成功 → 生成 JWT Token]
|
v
[前端保存 Token(localStorage)]
|
v
[携带 Authorization: Bearer xxx 请求后端接口]
|
v
[JWT 过滤器解析 Token → 构建用户上下文]
|
v
[Spring Security 判断权限 → 成功放行]
🧱 技术结构设计
✅ 1. 登录请求格式(包含角色)
json
POST /login
{
"username": "admin001",
"password": "123456",
"role": "ADMIN"
}
✅ 2. 后端 Controller 入口
java
@PostMapping("/login")
public R login(@RequestBody Account account) {
LoginStrategy strategy = loginStrategyFactory.getStrategy(account.getRole());
Account dbAccount = strategy.login(account);
if (dbAccount == null) return R.error("账号或密码错误");
String token = jwtUtils.createToken(dbAccount);
return R.ok().put("token", token).put("user", dbAccount);
}
✅ 3. 策略模式解耦多角色登录
java
public interface LoginStrategy {
Account login(Account account);
}
@Component("ADMIN")
public class AdminLoginStrategy implements LoginStrategy {
@Autowired private AdminService adminService;
public Account login(Account account) {
return adminService.login(account);
}
}
@Component("TEACHER")
public class TeacherLoginStrategy implements LoginStrategy {
@Autowired private TeacherService teacherService;
public Account login(Account account) {
return teacherService.login(account);
}
}
// 工厂类
@Component
public class LoginStrategyFactory {
@Autowired private Map<String, LoginStrategy> strategyMap;
public LoginStrategy getStrategy(String role) {
return strategyMap.get(role);
}
}
💡 这样写的好处是:当角色增加时无需修改核心逻辑,只需新增一个策略实现类即可。
✅ 4. JWT Token 工具类(核心方法)
java
public String createToken(Account account) {
return Jwts.builder()
.setSubject(account.getId().toString())
.claim("role", account.getRole())
.signWith(SignatureAlgorithm.HS256, secretKey)
.setExpiration(expireDate)
.compact();
}
✅ 5. JWT 过滤器 + Spring Security 认证链路
- 自定义
JwtAuthenticationFilter
解析请求头中的 Token; - 成功解析后,将用户信息封装为
UsernamePasswordAuthenticationToken
放入SecurityContextHolder
; - 后续的接口请求将被 Spring Security 统一管理是否有权限访问。
🔄 Token 前后端交互说明
步骤 | 说明 |
---|---|
登录成功 | 后端返回 Token + 用户信息 |
前端存储 | Vue3 使用 localStorage.setItem("token", xxx) |
接口调用 | Axios 请求头自动携带 Authorization: Bearer xxx |
权限判断 | 后端解析角色权限后放行 or 拒绝 |
🧠 常见问题解答
❓ 为何要传 role
参数?
因为多个角色可能存在相同账号(如 admin001 可能是老师又是管理员),必须指定登录身份。
❓ Token 中哪些信息需要加密?
用户 ID + 角色是必须的。密码不应放入 Token。可考虑加入签发时间、IP 白名单等增强信息。
❓ Token 过期怎么办?
目前系统使用短时间有效 Token + 刷新机制,可集成 Redis 实现 Token 黑名单。
📦 项目结构片段(后端)
plaintext
├── controller
│ └── LoginController.java
├── service
│ ├── AdminService.java
│ ├── TeacherService.java
├── strategy
│ ├── LoginStrategy.java
│ ├── AdminLoginStrategy.java
│ └── TeacherLoginStrategy.java
├── security
│ ├── JwtAuthenticationFilter.java
│ ├── JwtUtils.java
🔚 总结
通过 Spring Boot + JWT + 策略模式,我实现了一个功能完善、结构清晰的多角色登录认证体系:
- ✅ 无状态、轻量化、安全性强
- ✅ 支持多角色解耦,灵活扩展
- ✅ 支持 PC 登录、扫码登录等多终端适配
- ✅ 权限控制基于 Spring Security 精细化实现
这套机制也为后续的扫码登录、权限控制、动态菜单等功能奠定了基础。
🧭 下一篇预告
📌《如何用 Spring Security 构建无状态权限控制系统(含角色菜单控制)》
🔗 项目地址
- GitHub 源码:gitee.com/codevibe/gr...
- 欢迎 Star & 提 Issue
🙋♂️ 如果你觉得这篇文章有帮助:
- 点个赞 👍
- 收藏 ⭐
- 关注我 👇 持续发布 Spring Boot / Vue3 实战项目内容