Spring Boot整合JWT实现认证与授权的项目实践

 更新时间:2025年06月29日 11:36:00   作者:木子空间Pro  
JWT是开放标准,用于在Web应用中安全传输信息,常用于身份验证和信息交换,本文主要介绍了SpringBoot整合JWT实现认证与授权,具有一定的参考价值,感兴趣的可以了解一下

概述

JSON Web Token (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息。在Web应用中,JWT常用于身份验证和信息交换。

依赖配置

首先需要在项目中添加JWT依赖:

<!-- JWT依赖 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

JWT工具类封装

我们创建一个JwtUtil工具类来封装JWT的生成、解析和验证逻辑:

package com.bookstore.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {
    private static final String SECRET_KEY = "bookstore_secret_key";
    private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 24小时

    // 生成JWT令牌
    public String generateToken(Integer userId, String role) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userId);
        claims.put("role", role);
        
        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    // 解析JWT令牌
    public Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }

    // 验证JWT令牌
    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

JWT拦截器实现

创建拦截器来验证请求中的JWT令牌:

package com.bookstore.config;

import com.bookstore.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 放行OPTIONS请求
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }

        // 从请求头获取token
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            if (jwtUtil.validateToken(token)) {
                Claims claims = jwtUtil.parseToken(token);
                // 将用户信息存入request属性中
                request.setAttribute("userId", claims.get("userId"));
                request.setAttribute("role", claims.get("role"));
                return true;
            }
        }
        
        response.setStatus(401);
        return false;
    }
}

MVC配置

配置拦截器并设置拦截路径:

package com.bookstore.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private JwtInterceptor jwtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/**")  // 拦截所有路径
                .excludePathPatterns(    // 排除路径
                        "/login",
                        "/register",
                        "/swagger-resources/**",
                        "/webjars/**",
                        "/v3/api-docs/**",
                        "/swagger-ui.html/**",
                        "/error",
                        "/favicon.ico",
                        "doc.html",
                        "/logout",
                        "/static/**",
                        "/carousel/list",
                        "/book/new",
                        "/v2/api-docs"
                );
    }
}

使用示例

登录时生成令牌

在登录成功后生成JWT令牌并返回给客户端:

String token = jwtUtil.generateToken(foundUser.getId(), foundUser.getRole());

基础控制器

创建基础控制器方便获取已认证的用户信息:

import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;

public class BaseController {
    @Autowired
    protected HttpServletRequest request;
    
    // 获取当前用户ID
    protected Integer getCurrentUserId() {
        return (Integer) request.getAttribute("userId");
    }
    
    // 获取当前用户角色
    protected String getCurrentUserRole() {
        return (String) request.getAttribute("role");
    }

    // 检查是否是管理员
    protected boolean isAdmin() {
        return "admin".equals(getCurrentUserRole());
    }

    // 检查是否是普通用户
    protected boolean isUser() {
        return "user".equals(getCurrentUserRole());
    }
}

其他控制器可以继承BaseController来方便地获取用户信息:

@RestController
@RequestMapping("/api/books")
public class BookController extends BaseController {
    
    @GetMapping("/{id}")
    public ResponseEntity<Book> getBook(@PathVariable Integer id) {
        if (isAdmin()) {
            // 管理员特有逻辑
        }
        // 其他逻辑...
    }
}

总结

  • JWT工具类:封装了令牌的生成、解析和验证逻辑
  • 拦截器:自动验证请求中的JWT令牌并提取用户信息
  • MVC配置:灵活配置需要拦截和放行的路径
  • 基础控制器:提供便捷的方法获取当前用户信息

这种实现方式具有以下优点:

  • 无状态认证,服务端不需要存储会话信息
  • 跨域支持良好
  • 可以方便地携带用户信息
  • 适合分布式系统

在实际项目中,可以根据需求调整令牌的有效期、密钥的存储方式(如从配置中心获取)以及更精细的权限控制逻辑。

到此这篇关于Spring Boot整合JWT实现认证与授权的项目实践的文章就介绍到这了,更多相关Spring Boot JWT认证与授权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • 基于spring+quartz的分布式定时任务框架实现

    基于spring+quartz的分布式定时任务框架实现

    在Spring中的定时任务功能,最好的办法当然是使用Quartz来实现。这篇文章主要介绍了基于spring+quartz的分布式定时任务框架实现,有兴趣的可以了解一下。
    2017-01-01
  • Java设计模式之访问者模式

    Java设计模式之访问者模式

    这篇文章介绍了Java设计模式之访问者模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • SpringBoot使用Thymeleaf模板引擎访问静态html的过程

    SpringBoot使用Thymeleaf模板引擎访问静态html的过程

    这篇文章主要介绍了SpringBoot使用Thymeleaf模板引擎访问静态html的过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Java 通过JDBC连接Mysql数据库

    Java 通过JDBC连接Mysql数据库

    本文给大家详细介绍了java如何使用JDBC连接Mysql的方法以及驱动包的安装,最后给大家附上了java通过JDBC连接其他各种数据库的方法,有需要的小伙伴可以参考下。
    2015-11-11
  • idea多环境配置及问题解决方案

    idea多环境配置及问题解决方案

    这篇文章主要介绍了idea多环境配置及问题解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Spring Security中集成JWT的完整实战指南

    Spring Security中集成JWT的完整实战指南

    本文深入探讨了现代Web应用中的认证授权方案,对比分析了JWT、Session-Cookie、OAuth2/OIDC、SAML 2.0等主流方案的优缺点及适用场景,感兴趣的小伙伴可以了解下
    2026-05-05
  • Java单机环境实现定时任务技术

    Java单机环境实现定时任务技术

    这篇文章主要介绍了Java单机环境实现定时任务技术,文章内容介绍详细,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-04-04
  • Spring Security单项目权限设计过程解析

    Spring Security单项目权限设计过程解析

    这篇文章主要介绍了Spring Security单项目权限设计过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 解决CentOS7中运行jar包报错:xxx(Permission denied)

    解决CentOS7中运行jar包报错:xxx(Permission denied)

    在实际工作我们经常会在linux上运行Spring boot编写的微服务程序,下面这篇文章主要给大家介绍了关于如何解决CentOS7中运行jar包报错:xxx(Permission denied)的相关资料,需要的朋友可以参考下
    2024-02-02
  • 纯Java实现数字证书生成签名的简单实例

    纯Java实现数字证书生成签名的简单实例

    下面小编就为大家带来一篇纯Java实现数字证书生成签名的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08

最新评论