/jwt-auth-service

jwt-auth-service

Primary LanguageJava

JWT双Token认证和续租方案

项目介绍

这是一个基于Spring Boot的微服务单体应用,实现了JWT双Token(访问令牌和刷新令牌)的授权和续租方案。该项目提供了完整的用户认证、授权和令牌管理功能。

技术栈

  • Spring Boot 2.7.5
  • Spring Security
  • Spring Data JPA
  • Spring Data Redis
  • H2 Database (开发环境)
  • JWT (JSON Web Token)
  • Lombok

功能特性

  • 用户注册和登录
  • 基于JWT的双Token认证机制
    • 短期访问令牌(Access Token):用于API访问认证
    • 长期刷新令牌(Refresh Token):用于获取新的访问令牌
  • 令牌自动续租机制
  • 基于角色的访问控制(RBAC)
  • Redis存储刷新令牌,提高安全性
  • 全局异常处理

项目结构

src/main/java/com/example/jwtauthservice/
├── JwtAuthServiceApplication.java        # 应用程序入口
├── config/                               # 配置类
│   ├── DataInitializer.java              # 数据初始化
│   ├── RedisConfig.java                  # Redis配置
│   └── WebSecurityConfig.java            # Spring Security配置
├── controller/                           # 控制器
│   ├── AuthController.java               # 认证控制器
│   └── TestController.java               # 测试控制器
├── entity/                               # 实体类
│   ├── ERole.java                        # 角色枚举
│   ├── Role.java                         # 角色实体
│   └── User.java                         # 用户实体
├── exception/                            # 异常处理
│   ├── GlobalExceptionHandler.java       # 全局异常处理器
│   └── TokenRefreshException.java        # 令牌刷新异常
├── payload/                              # 数据传输对象
│   ├── request/                          # 请求DTO
│   │   ├── LoginRequest.java             # 登录请求
│   │   ├── SignupRequest.java            # 注册请求
│   │   └── TokenRefreshRequest.java      # 令牌刷新请求
│   └── response/                         # 响应DTO
│       ├── JwtResponse.java              # JWT响应
│       ├── MessageResponse.java          # 消息响应
│       └── TokenRefreshResponse.java     # 令牌刷新响应
├── repository/                           # 数据访问层
│   ├── RoleRepository.java               # 角色仓库
│   └── UserRepository.java               # 用户仓库
└── security/                             # 安全相关
    ├── jwt/                              # JWT相关
    │   ├── AuthEntryPointJwt.java        # JWT认证入口点
    │   ├── AuthTokenFilter.java          # JWT认证过滤器
    │   ├── JwtUtils.java                 # JWT工具类
    │   └── TokenPair.java                # 令牌对实体
    └── service/                          # 安全服务
        ├── RefreshTokenService.java      # 刷新令牌服务
        ├── UserDetailsImpl.java          # 用户详情实现
        └── UserDetailsServiceImpl.java   # 用户详情服务实现

双Token认证流程

  1. 用户登录

    • 用户提供用户名和密码
    • 服务器验证凭据
    • 生成访问令牌(短期有效,如5分钟)和刷新令牌(长期有效,如7天)
    • 将刷新令牌存储在Redis中
    • 返回两个令牌给客户端
  2. API访问

    • 客户端在请求头中携带访问令牌
    • 服务器验证访问令牌的有效性
    • 如果有效,允许访问受保护资源
    • 如果无效或过期,返回401错误
  3. 令牌续租

    • 当访问令牌过期时,客户端使用刷新令牌请求新的访问令牌
    • 服务器验证刷新令牌的有效性和存在性
    • 如果有效,生成新的访问令牌并返回给客户端
    • 如果无效,客户端需要重新登录
  4. 用户登出

    • 客户端请求登出
    • 服务器从Redis中删除刷新令牌
    • 客户端删除本地存储的令牌

安全特性

  • 访问令牌短期有效,减少被盗用的风险
  • 刷新令牌存储在Redis中,可以随时撤销
  • 密码使用BCrypt加密存储
  • 基于角色的访问控制,精细化权限管理
  • 全局异常处理,提供友好的错误信息

使用说明

环境要求

  • JDK 11+
  • Maven 3.6+
  • Redis (可选,默认使用内嵌模式)

运行项目

  1. 克隆项目
  2. 进入项目目录
  3. 运行命令:mvn spring-boot:run
  4. 访问:http://localhost:8080

API接口

认证接口

  • 注册:POST /api/auth/signup
  • 登录:POST /api/auth/signin
  • 刷新令牌:POST /api/auth/refreshtoken
  • 登出:POST /api/auth/signout

测试接口

  • 公开内容:GET /api/test/all
  • 用户内容:GET /api/test/user
  • 管理员内容:GET /api/test/admin
  • 版主内容:GET /api/test/mod

配置说明

主要配置在application.yml文件中:

# JWT配置
jwt:
  secret: mySecretKey123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
  access-token:
    expiration: 300000  # 5分钟,单位:毫秒
  refresh-token:
    expiration: 604800000  # 7天,单位:毫秒

可以根据需要调整令牌的过期时间和密钥。

注意事项

  • 生产环境中应使用更强的密钥
  • 考虑使用HTTPS保护API通信
  • 根据实际需求调整令牌过期时间
  • 生产环境应替换H2数据库为MySQL等持久化数据库