如何在springboot项目中使用JWT

这篇具有很好参考价值的文章主要介绍了如何在springboot项目中使用JWT。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、JWT是什么

JWT的全称为:JSON Web Token ,它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

2、JWT的组成

JWT由三部分组成,它们之间用圆点(.)连接。这三部分分别是:
Header.Payload.Signature

  1. Header是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256)。
  2. Payload是有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择。
  3. Signature是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。
  4. 完整的JWT如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI0NDAxODQyMDAwMDAwMDAwMDAifQ.Q7bE35fu4ZrE8FHF9HJfwAEV_pAYOtzYGDw5EVAnGts

3、JWT的用途

  1. 客户端使用用户名和密码请求登录
  2. 服务端收到请求,验证用户名和密码
  3. 验证成功后,服务端会签发一个token,再把这个token返回给客户端
  4. 客户端收到token后可以把它存储起来,比如放到cookie中
  5. 客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
  6. 服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据

4、为什么使用JWT

不动产预约登记系统项目开发初期,我试图用session来保存暂时需要保存或者暂时生成的数据,例如保存用户的账号密码记住用户登录的状态、保存各行政区的预约号球数量、保存用户当天取消预约次数等。但是使用session应用于前后端分离项目存在一定的弊端,例如由于session是存在与服务器的物理内存中,所以在分布式系统中,这种方式将会失效、因为session认证本质基于cookie,由于基于Cookie,而cookie无法跨域,所以session的认证也无法跨域,对单点登录不适用。所以使用session来进行开发项目并可行。
在这时了解到了JWT。结合项目场景的使用,JWT能满足项目基本功能的开发,原因有一下几点:

  1. 因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持。
  2. 不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端,特别适用于分布式微服务。
  3. 单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话,token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题。
  4. 适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie保存 SessionId),所以不适合移动端。

5、如何在项目中使用JWT

1、引入依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

2、生成token

根据使用场景,需要将生成token的方法写到对应的类中。在开发不动产预约登记系统中,我将生成token的方法写在了用户的基类中:

public class Account {//用户信息
    String id;
    String email;
    String username;
    String password;
    int cancelnum;

    public String getToken(Account account) {
        String token="";
        token= JWT.create().withAudience(account.getId())
                .sign(Algorithm.HMAC256(account.getPassword()));
        return token;
    }
}

为了确保token的唯一性,需要将用户的id以及password写入到token中进行加密.

3、开放路径

@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                .addInterceptor(authorizeInterceptor)
                .addPathPatterns("/**");// 拦截所有请求,通过判断是否有 @LoginRequired 注解 决定是否需要登录
    }

需要开放路径因为拦截器需要对全局路径进行扫描。

4、配置拦截器

public class AuthorizeInterceptor implements HandlerInterceptor {
    @Resource
    UserMapper mapper;

    String token;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释,有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 执行认证
                if (token == null) {
                    throw new RuntimeException("无token,请重新登录");
                }
                // 获取 token 中的 user id
                String email;
                try {
                    email = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                Account account = mapper.findAccountByEmail(email);
                if (account == null) {
                    throw new RuntimeException("用户不存在,请重新登录");
                }
                // 验证 token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(account.getPassword())).build();
                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {
    }

}

5、使用

根据项目功能,需要在登录接口写入注解以进行生成token并返回。

@UserLoginToken
    @PostMapping("/login2")//登录接口
    public Object login(@Pattern(regexp = EMAIL_REGEX) @Length(min = 10, max = 20) @RequestParam("email") String email,
                                  @Length(min = 6, max = 16) @RequestParam("password")String password,HttpSession session){
        JSONObject jsonObject=new JSONObject();
        Account account=service.login(email,password);
        if(account==null){
            jsonObject.put("status",401);
            jsonObject.put("success",false);
            jsonObject.put("message","登录失败,账号或密码错误");
            return jsonObject;
        }else  {
                String token = account.getToken(account);
                jsonObject.put("status",200);
                jsonObject.put("success",true);
                jsonObject.put("Token", token);
                jsonObject.put("message", account);
                return jsonObject;
            }
    }

6、运行效果

jwt springboot,spring boot,java,spring

部分参考、引用:

https://blog.csdn.net/weixin_45070175/article/details/118559272文章来源地址https://www.toymoban.com/news/detail-713281.html

到了这里,关于如何在springboot项目中使用JWT的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用IDEA创建使用 JDK8 的 2.x.x 版本的 Spring Boot 项目以及 Spring Boot 项目如何修改JDK版本

    目录 一、在阿里云上官网上创建项目 二、将 IDEA 中创建项目的源地址修改为阿里云官网 三、创建 3.x.x 的项目之后修改配置降低至 2.7.x 版本和使用 JDK8(修改 Spring Boot 的 JDK 版本同理) 从上面的 Spring Boot 官网的截图中可以发现,自 2023-11-24 之后,最后一个支持使用 JDK8 的

    2024年01月21日
    浏览(68)
  • Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题

    最近运行java项目的过程中,遇到一个问题。 在 @檀越 的远程指导下,一步步调试的过程中,发现是由于大小写不一致,导致判断不是同一个字段导致的。 最后将equals()替换为equalsIgnoreCase()后,成功解决问题 ! equals() 会判断大小写区别,equalsIgnoreCase() 不会判断大小写。 好久

    2024年02月03日
    浏览(63)
  • 【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目

    我本来以为是 IDEA 版本更新导致的 Bug,开始还没在意。 直到我今天自己初始化项目时才发现:卧槽,Java 8 真没了?! 具体一点,应该是使用 IDEA 内置的 Spring Initializr 创建 Spring Boot 新项目时,没有 Java 8 的选项了,只剩下了 = 17 的版本 去网上搜了一圈,原来这是因为 Sprin

    2024年02月04日
    浏览(45)
  • Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径

    在Spring Boot项目开发过程中,对于接口API发布URL访问路径,一般都是在类上标识 @RestController 或者 @Controller 注解,然后在方法上标识 @RequestMapping 相关注解,比如: @PostMapping 、 @GetMapping 注解,通过设置注解属性,发布URL。在某些场景下,我觉得这样发布URL太麻烦了,不适用,

    2024年03月22日
    浏览(66)
  • 【SpringBoot】Spring Boot 项目中整合 MyBatis 和 PageHelper

    目录 前言         步骤 1: 添加依赖 步骤 2: 配置数据源和 MyBatis 步骤 3: 配置 PageHelper 步骤 4: 使用 PageHelper 进行分页查询 IDEA指定端口启动 总结         Spring Boot 与 MyBatis 的整合是 Java 开发中常见的需求,特别是在使用分页插件如 PageHelper 时。PageHelper 是一个针对 MyBat

    2024年04月25日
    浏览(53)
  • 如何创建 Spring Boot 项目

    目录 一、Spring Boot 项目的创建 1. 安装 Spring Boot Helper 插件 2. 创建 Spring Boot 项目 3. 项目目录详解 4. 运行 Spring Boot 项目 二、Spring Boot 的优点 前言     Spring Boot 的意思就是 Spring Boot 脚手架的意思,已经总结完成 Spring 的学习,Spring 框架的诞生就是为了简化 Java程序的开发,而

    2024年02月15日
    浏览(43)
  • Spring Boot进阶(51):Spring Boot项目如何集成 HTML?| 超级详细,建议收藏

            我们都知道,Spring Boot作为一款广泛应用于企业级的开发框架,其通过简化开发过程、提高开发效率赢得了众多开发者的青睐。在实际项目开发中,集成 HTML作为 Web 应用程序中的一个基本需求,也是现在极其常见的场景之一。在此,我将为大家分享一下Spring Boot如何

    2024年02月15日
    浏览(54)
  • idea如何导入配置Spring Boot项目

    1、打开idea,点击File-open选择要打开的springBoot项目 2、然后配置Maven,选择File-Settings里面的Build ,Excution,Deployement里面的Build Tools里面的Maven,如果没有配置maven镜像,直接使用默认的Bundels(Maven3)点击ok即可,不过这样下载很慢,如果弹出import changes,点击这个即可,如果配置了

    2024年02月17日
    浏览(60)
  • Spring Boot学习随笔-第一个SpringBoot项目快速启动(org.springframework.boot、@SpringBootApplication、application.yml)

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 创建第一个Module 环境要求 jdk1.8+ maven3.2+ Spring Framework 5.x+ Tomcat 9.0+ IDEA 2021 自动保存刷新pom 在resources下添加application.yml文件后,即可启动springboot应用 由于tomcat内嵌在springboot里面了,所以我们在修改端口号等设置也在配置

    2024年02月05日
    浏览(59)
  • IDEA 中搭建 Spring Boot Maven 多模块项目 (父SpringBoot+子Maven)

    [Ref] 新建一个SpringBoot项目 删除无用的 .mvn 目录、 src 目录、 mvnw 及 mvnw.cmd 文件,最终只留 .gitignore 和 pom.xml ① 删除 dependencies 标签及其中的 spring-boot-starter 和 spring-boot-starter-test 依赖,因为 Spring Boot 提供的父工程已包含,并且父 pom 原则上都是通过 dependencyManagement 标签管理

    2024年01月20日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包