jwt生成token和验证token以及获取playload的数据,实现token拦截

2023-11-15

jwt实现流程:

在这里插入图片描述

1.添加依赖:

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

2.编写一个jwt的工具类

package com.springboot.jwt.common;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.io.UnsupportedEncodingException;
import java.util.Date;

public class JWTUtil {

    //过期时间设置
    private static final long EXPIRE_TIME = 5 * 60 * 1000;
   // private static final long EXPIRE_TIME = 10 * 1000;
    private static final String SECRET="admintor123service";  //密钥盐
    /**
     * 签名验证
     * @param token
     * @return
     */
    public static boolean verif(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer("auth0")
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("issuer: " + jwt.getIssuer());
            System.out.println("username: " + jwt.getClaim("username").asString());
            System.out.println("过期时间:      " + jwt.getExpiresAt());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @param token
     * @return
     */
    public static String getUserName(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 签名生成
     * @param username
     */
        public static String sign(String username) {
        String token = null;
        try {
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            token = JWT.create().withIssuer("auth0").withClaim("username", username).withExpiresAt(date).sign(algorithm);
            return token;
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

}

3.JWT中的三个主要方法和三个对象

在这里插入图片描述
在这里插入图片描述
4.生成token的主要方法:
token = JWT.create().withIssuer(“auth0”).withClaim(“username”, username).withExpiresAt(date).sign(algorithm);
可以看看sign()方法做了什么事情,如下:

在这里插入图片描述

在这里插入图片描述

5.所以生成token需要三部分数据:

5.1.header:头部(一般不需要处理,主要在sign方法传入算法对象即可)

this.headerClaims.put("alg", algorithm.getName());                this.headerClaims.put("typ", "JWT");

5.2.payload:载体(用于配置基本信息和添加其他信息到token)

//基本信息的方法
public JWTCreator.Builder withKeyId(String keyId) {
     this.headerClaims.put("kid", keyId);
     return this;
 }
	//jwt发行者
 public JWTCreator.Builder withIssuer(String issuer) {
     this.addClaim("iss", issuer);
     return this;
 }
//jwt主题
 public JWTCreator.Builder withSubject(String subject) {
     this.addClaim("sub", subject);
     return this;
 }
//接收jwt的用户
 public JWTCreator.Builder withAudience(String... audience) {
     this.addClaim("aud", audience);
     return this;
 }
//jwt的过期时间
 public JWTCreator.Builder withExpiresAt(Date expiresAt) {
     this.addClaim("exp", expiresAt);
     return this;
 }
//在上面时间之前,jwt不可用
 public JWTCreator.Builder withNotBefore(Date notBefore) {
     this.addClaim("nbf", notBefore);
     return this;
 }
//jwt的发行时间
 public JWTCreator.Builder withIssuedAt(Date issuedAt) {
     this.addClaim("iat", issuedAt);
     return this;
 }

 public JWTCreator.Builder withJWTId(String jwtId) {
     this.addClaim("jti", jwtId);
     return this;
 }

//添加其他信息的方法
 public JWTCreator.Builder withClaim(String name, Boolean value) throws IllegalArgumentException {
            this.assertNonNull(name);
            this.addClaim(name, value);
            return this;
        }

5.3.signature:签名(不需要处理,内部方法处理)

签名的生成是由头部数据和载体数据通过算法生成的签名数据。

byte[] signatureBytes = this.algorithm.sign(content.getBytes(StandardCharsets.UTF_8));
String signature = Base64.encodeBase64URLSafeString(signatureBytes);

6.从token中获取payload载体的数据,通过JWT.decode(token)获取DecodeJWT对象。

    public static String getUserName(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

说明:
主要通过DecodeJWT对象的getClaim方法获取。chaim对象是一个map,getClaim()就是调用map的get()方法。

7.jwt验证token的载体数据,如果载体的数据与生成token时的载体数据能匹配上,接口的请求就通过,否则不通过,通过拦截器来实现拦截。具体实现如下:

说明:
主要通过JWTVerifier验证器的verify()方法来验证token。

    public static boolean verif(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer("auth0")
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

看看verify(token)方法做了什么,如下: 说明: 主要验证算法对象,签名,和Claim的数据(也就是payload载体的数据)

在这里插入图片描述

6.1验证算法对象

在这里插入图片描述

6.2验证签名

在这里插入图片描述

6.3Claim的数据(也就是payload载体的数据)

在这里插入图片描述

7.自定义拦截器TokenInterceptor.java,在拦截器中进行token的验证。

package com.springboot.jwt.common.intercepter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.springboot.jwt.common.JWTUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      if(request.getMethod().equals("OPTIONS")){
          response.setStatus(HttpServletResponse.SC_OK);
          return true;
      }

    String token = request.getHeader("token");
    if(token !=null){
        boolean result = JWTUtil.verif(token);
        if(result){
            return true;
        }
    }
        response.setCharacterEncoding("utf-8");
    response.setContentType("application/json;charset=utf-8");
        PrintWriter out = null;
        try{
            Map map = new HashMap<String,Object>();
            map.put("success", false);
            map.put("msg", "认证失败,未通过拦截器");
            response.getWriter().write(new ObjectMapper().writeValueAsString(map));
        }catch (Exception e){
            e.printStackTrace();
            response.sendError(500);
            return false;
        }
        return false;
    }


}

8.在webmvcconfig中,通过重写addInterceptors(InterceptorRegistry registry)方法,注册自定义的过滤器:

package com.springboot.jwt.common.config;

import com.springboot.jwt.common.intercepter.TokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
/*    private TokenInterceptor tokenInterceptor;
    //构造方法
    public InterceptorConfig(TokenInterceptor tokenInterceptor){
        this.tokenInterceptor =tokenInterceptor;
    }*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> excludePath = new ArrayList<>();
        excludePath.add("/login");//登录
        excludePath.add("/register");//注册
        excludePath.add("/logout");//登出
        excludePath.add("/static/**");  //静态资源
        excludePath.add("/assets/**");  //静态资源
    registry
        .addInterceptor(new TokenInterceptor())
        .addPathPatterns("/**")
        .excludePathPatterns(excludePath);
   // WebMvcConfigurer.super.addInterceptors(registry);
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jwt生成token和验证token以及获取playload的数据,实现token拦截 的相关文章

随机推荐

  • python计算机视觉第五次实验

    相机标定 Camera calibration 摄像机标定简单来说是从世界坐标系转换为相机坐标系 再由相机坐标系转换为图像坐标系的过程 也就是求最终的投影矩阵P的过程 世界坐标系 用户定义的三维世界的坐标系 为了描述目标物在真实世界里的位置
  • vite项目中处理各种静态资源的引入方式介绍

    一 引用图片资源 在vite创建的vue3项目中 引用图片资源有以下两种方式 直接在模板中使用路径引用 在模板中使用标签 通过src属性引用图片 例如
  • Python os.path() 模块

    os path 模块主要用于获取文件的属性 以下是os path 模块的几种常用方法 方法 说明 os path abspath path 返回绝对路径 os path basename path 返回路径中最后一个元素 以 结尾时返回空字
  • 静态代码扫描(六)——火线针对资源关闭问题的横向对比报告

    在上一篇文章中 我们列举了一些资源关闭需要考虑的特殊场景 并且预告了会在这篇放出火线和其他开源产品横向的扫描结果对比报告 包括Sonar Infer PMD和Findbugs 由于Lint没有针对资源关闭的规则 未加入对比 一 对比结果 我
  • Ubuntu更改CMAKE和C++版本

    在代码移植的过程中 因为ubuntu版本的不同 经常会出现代码在新环境中编译不通过 其中有很多因素是因为camke和C 的版本不同 下面将给出方案 更改Cmake版本 sudo apt remove cmake 删除旧版本的cmake su
  • idea 集成 rest api 测试工具 相当于 postman

    HTTP Client IntelliJ IDEs Plugin Marketplace
  • Type C --- 引脚图解

  • 小程序项目结构及项目启动过程和页面渲染过程

    微信开发者初识 编辑器 一级工具 项目 gt 退出当前项目 格式化代码 gt shift alt f 工具 gt 构建npm 详情 gt 本地设置 使用npm模块 不校验合法域名 项目结构 项目结构 pages 视图组件 页面 由四个文件组
  • CentOS 7 保姆级图文详细安装部署Apache教程

    目录 前言 一 HTTP协议介绍 二 安装依赖 三 安装apr 四 APR util安装 五 apr iconv安装 六 Apache安装 七 启动和测试Apache 国外官方 Apache 相关组件官方下载列表 Apache Distri
  • 对全连接层的理解

    1 1概述 全连接层 Fully Connected Layer 一般位于整个卷积神经网络的最后 负责将卷积输出的二维特征图转化成一维的一个向量 由此实现了端到端的学习过程 即 输入一张图像或一段语音 输出一个向量或信息 全连接层的每一个结
  • url服务器显示错误,服务器地址 (URL) 错误无效错误 - Dynamics 365 Sales

    为 Outlook 配置 时 URL Microsoft Dynamics CRM 无效 错误 3 31 2021 本文内容 本文提供了当您尝试将 Outlook 的 Microsoft Dynamics CRM 连接到您的 Microso
  • st语言编程手册plc_三菱Q系列PLC,ST语言的IF语句、CASE语句指令格式

    IF语句和CASE语句是ST编程语言中的选择 条件 语句的两种形式 1 如果 IF BOOL事件 1 0 那么 THEN 结果 语句 END IF 2 如果 IF BOOL事件 1 0 那么 THEN 结果 语句1 否则ELSE 语句2 E
  • Python 对加减乘除分别封装一个函数进行计算,参数是两个数,返回值是计算结果

    1 对加减乘除分别封装一个函数进行计算 参数是两个数 返回值是计算结果 def add x y param x param y return 返回结果 print x y return add 3 4 def sub x y param x
  • 动态菜单/权限管理的实现

    权限管理 序 现在基本上大大小小的系统都由权限分配这一基础功能 不同的用户看到的界面不一样 能够使用的功能也不会尽然相同 所以我要让我的系统做到超级管理员可以看到 操作所有界面 而新闻管理员只能看到新闻管理模块 仓库管理员只能看到仓库管理模
  • 基于openwrt,aria2下载器安装与配置

    迅雷下载不好用 所以用这个下载器aria2 需要安装软件 在可用软件列表中安装aria2和luci app aria2 安装完后有可能需要重启路由器 需要注意的问题 1 aria2只是一个下载工具 并没有图形界面 2 文件下载的位置 在ar
  • 在传统公司干IT是一种什么体验(六)

    不要轻视任何一家传统公司 传统公司能够在激烈的竞争中活下来 都有自己的绝活 表哥语录 表哥虽然经常吐槽自己的公司 但是大部分都是对传统公司的文化和风格的不适应 任何一家传统公司 能够在长达十几年甚至几十年的市场竞争中活下来 一定有自己的独门
  • 数据库开发之MySql(下)(多表查询)

    多表查询 介绍 多表查询就是指从多张表中查询数据 笛卡尔积 笛卡尔乘积是指在数学中 两个集合A集合 和 B集合的所有组合情况 在多表查询时 需要消除无效的笛卡尔积 怎么做多表查询的需求 要查询的数据涉及到哪些表 找出关联条件 外键 主键 其
  • STM32---独立看门狗

    文章目录 前言 一 看门狗概述 1 背景 2 工作原理 二 使用步骤 1 添加复位检测代码 2 喂狗时间设置 3 喂狗 4 喂狗技巧 三 应用领域 四 源码地址 总结 前言 STM32 独立看门狗 提示 以下是本篇文章正文内容 下面案例可供
  • RuntimeError: expected scalar type Long but found Float

    通过检查打印数据格式 发现数据是 torch int64 将数据转换成 float即可 torch tensor data dtype torch float
  • jwt生成token和验证token以及获取playload的数据,实现token拦截

    jwt实现流程 1 添加依赖