使用 Spring Boot + JWT 实现多角色登录认证(附完整流程图)

本文是「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 构建无状态权限控制系统(含角色菜单控制)》


🔗 项目地址


🙋‍♂️ 如果你觉得这篇文章有帮助:

  • 点个赞 👍
  • 收藏 ⭐
  • 关注我 👇 持续发布 Spring Boot / Vue3 实战项目内容
相关推荐
ZBritney12 小时前
JAVA中的多线程
java
whn197712 小时前
达梦数据库的整体负载变化查看
java·开发语言·数据库
小满、12 小时前
RabbitMQ:Fanout、Direct、Topic 交换机、队列声明与消息转换器
java·分布式·消息队列·rabbitmq·spring amqp
JaguarJack12 小时前
使用 PHP 和 WebSocket 构建实时聊天应用 完整指南
后端·php
檀越剑指大厂13 小时前
【Idea系列】换行处理
java·ide·intellij-idea
wanghowie13 小时前
01.04 Java基础篇|泛型、注解与反射实战
java·开发语言·windows
深圳佛手13 小时前
Java大对象(如 List、Map)如何复用?错误的方法是?正确的方法是?
java·jvm·windows
言之。13 小时前
Claude Code Skills 实用使用手册
java·开发语言
苹果醋313 小时前
JAVA设计模式之策略模式
java·运维·spring boot·mysql·nginx
CodeSheep13 小时前
中国四大软件外包公司
前端·后端·程序员