JWT生成tonken验证+AOP拦截验证

news2025/1/11 9:58:51

JSON Web Token(JWT)是目前都在用的前后分离跨域验证规则。

JWT由3部分组成

  • Header——头部一般Base64URL编码,作用:声明token类型,声明token使用的加密算法。一般都是使用HMAC-SHA256或者RSA支持很多种算法(HS256、HS384、HS512、RS256、RS384、RS512、ES256、ES384、ES512、PS256、PS384)
  • PayLoad——载荷(自定义数据)也叫消息体(payload)是一个JSON对象。一般Base64URL编码。存储用户信息,过期时间等等。。。因为载荷里面包含可以包含许多用户自定义信息,所以后端不用再频繁的与数据库进行交互,可以直接获取信息。但是这也导致载荷里不建议储存敏感信息,因为可以直接Base64URL解密就能看到了,当然你也可以额外再加密。  这些有效信息包含三个部分:标准中注册的声明、公共的声明和私有的声明
  • Signature(签名其实是由Header+PayLoad+自定义密钥再由加密算法(HS256)或者其他算法生成。这也是jwt安全的真正原因)

1、引入依赖pom.xml

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

2、编写jwt工具类JwtUtil.java

package com.muchuantong.util;

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

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

/**
 * @Author: Zou Tiancong
 * @Date: 2021/12/1 0001 10:37
 * @Annotation:jwtToken
 */
public class JwtUtil {

	// 设置过期时间
	private static final long EXPIRE_DATE = 60*1000;
	// token秘钥
	private static final String TOKEN_SECRET = "TEST-AUTH-TOKEN";

	// 实现签名方法
	public static String token(String id, String openId, String nickName) {

		String token = "";
		try {
			// 这里将用户存入了Token,在下面的解析中,也会有解析的方法可以获取到Token里面的数据
			// Token过期的时间
			Date expireDate = new Date(System.currentTimeMillis() + EXPIRE_DATE);
			// 秘钥及加密算法
			Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
			// 设置头部信息,类型以及签名所用的算法
			Map<String, Object> header = new HashMap<>();
			header.put("typ", "JWT");
			header.put("alg", "HS256");
			// 携带用户信息,存入token,生成签名
			token = JWT.create()
					.withHeader(header) //设置头部信息Header
					.withIssuer("TEST") //设置签名是由谁生成
					.withSubject("AUTH-TOKEN") //设置签名的主题
					.withAudience(nickName) //设置签名的观众
					.withIssuedAt(new Date()) //设置生成签名的时间
					.withExpiresAt(expireDate) //设置签名过期的时间
					.withClaim("id", id) //自定义信息
					.withClaim("openId", openId)//自定义信息
					.withClaim("nickName", nickName)//自定义信息
					.withJWTId(id) //jwt的id,主要用来作为一次性token,从而回避重放攻击
					.sign(algorithm);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return token;
	}

	// 验证token
	public static boolean verify(String token) {
		/**
		 * @desc 验证token,通过返回true
		 * @params [token]需要校验的串
		 **/
		try {
			Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
			JWTVerifier verifier = JWT.require(algorithm).build();
			DecodedJWT jwt = verifier.verify(token);
			String subject = jwt.getSubject();
			List<String> audience = jwt.getAudience();
			Map<String, Claim> claims = jwt.getClaims();
			System.out.println(subject+"*******"+audience);
			for (Map.Entry<String, Claim> entry : claims.entrySet()){
				String key = entry.getKey();
				Claim claim = entry.getValue();
				String value = claim.asString();
				System.out.println("key:"+key+" value:"+value);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Token已过期,需要重新登录");
		}
		return false;
	}

	// 生成token
	public static String setToken(String id, String openId, String nickName) {
		String token = token(id, openId, nickName);
		return token;
	}

}

2、自定义注解接口Auth.java

package com.muchuantong.util;

import java.lang.annotation.*;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: ZouTiancong
 * @Date: 2022/05/23/22:37
 * @Description:
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {
    boolean token() default true;
}

3、自定义注解APO实现类AuthAspect.java

package com.muchuantong.util;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: ZouTiancong
 * @Date: 2022/05/23/22:39
 * @Description:
 */
@Component
@Aspect
public class AuthAspect {
	@Autowired
	private HttpServletRequest request;

	@Pointcut("@annotation(com.muchuantong.util.Auth)")
	private void authPointcut() {
	}

	@Around("authPointcut()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		// 获取方法签名信息从而获取方法名和参数类型
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

		// 获取目标方法对象上注解中的属性值
		Auth auth = methodSignature.getMethod().getAnnotation(Auth.class);

		// 校验签名
		if (auth.token()) {
			boolean token = JwtUtil.verify(request.getHeader("token"));
			// 如果token校验失败返回
			if (!token) {
				return new Result<>("401", "token已过期,请重新登录!");
			}
		}
		return joinPoint.proceed();
	}
}

4、在需要token验证的地方加入注解@Auth

 5、前端调用查看效果,token生成返回成功,后端也能成功读取数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/54058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

岩藻多糖-聚乙二醇-刀豆球蛋白A,ConcanavalinA-PEG-Fucoidan,刀豆球蛋白A-PEG-岩藻多糖

岩藻多糖-聚乙二醇-刀豆球蛋白A&#xff0c;ConcanavalinA-PEG-Fucoidan&#xff0c;刀豆球蛋白A-PEG-岩藻多糖 中文名称&#xff1a;岩藻多糖-刀豆球蛋白A 英文名称&#xff1a;Fucoidan-ConcanavalinA 别称&#xff1a;刀豆球蛋白A修饰岩藻多糖&#xff0c;ConA-岩藻多糖 …

分享从零开始学习网络设备配置--任务2.6 避免网络环路

任务描述 某公司最近由于业务迅速发展和对网络可靠性的要求&#xff0c;使用了两台高性能交换机作为核心交换机&#xff0c;接入层交换机与核心层交换机互联&#xff0c;形成冗余结构&#xff0c;来满足网络的可靠性&#xff0c;达到最佳的工作效率。 生成树技术&#xff08;S…

在一次又一次的失败中, 我总结了这份万字的《MySQL 性能调优笔记》

MySQL 性能调优学习导图》概要 说明&#xff1a;本文篇幅有限&#xff0c;故只展示部分内容&#xff0c;《MySQL 性能调优学习导图》资料已整理成文档&#xff0c;需要获取的小伙伴可以直接转发关注后私信&#xff08;学习&#xff09;即可获取哦 一、性能监控 1. 使用 show p…

2022/12/1 结构体

结构体 声明结构体&#xff1a; struct 结构体名 例如&#xff1a;struct student 其中&#xff0c;student又称为结构体标记 结构体可以拥有成员&#xff0c;例如&#xff1a; struct student { int num; int score; char name[20] }; 注意&#xff0c;分号不可以少…

万应低代码11月重点更新内容速递

速览版 详情版 低代码开发效率升级 1.页面变量支持快速构建 在「数据提交」、「调用逻辑」等存在数据返回的节点中&#xff0c;支持根据其输出的内容去自动创建数据类型相同的变量&#xff0c;并自动建立好映射关系。 ● 【功能上线前】&#xff1a; 需要为每一个输出字…

Elasticsearch_第一章_ elasticsearch基础

Elasticsearch_第一章_ elasticsearch基础 – elasticsearch基础 文章目录Elasticsearch_第一章_ elasticsearch基础0.学习目标1.初识elasticsearch1.1.了解ES1.1.1.elasticsearch的作用1.1.2.ELK技术栈1.1.3.elasticsearch和lucene1.1.4.为什么不是其他搜索技术&#xff1f;1…

企业该如何选择自己合适的云财务软件?

据相关数据统计&#xff0c;2021年&#xff0c;我国云服务市场规模达274亿美元&#xff08;超1700亿元人民币&#xff09;&#xff0c;预计到2026年将增长至850亿美元&#xff08;约5400亿元人民币&#xff09;。可见&#xff0c;云服务市场的发展之迅。对于企业而言&#xff0…

python入门项目03:完成黑心资本家发工资的程序

本题来源于黑马程序员b站视频&#xff0c;如有侵权&#xff0c;请联系删除。 import random #总金额10000 all_money10000 n0#记录发放工资的人 #发工资 for i in range(1,21):#20个员工jixiaorandom.randint(1,10)#生成一个1&#xff0c;10的随机数if jixiao<5:print(f员工…

12.1排序

目录 0.修改栈堆内存 一.堆排序 1 原理 2.代码实现 3.分析 二.冒泡排序 1 原理 2.实现 3.分析 三.快速排序(重要) 1 原理-总览 2.方法:挖坑法 步骤一 步骤二 步骤三 步骤四 步骤五 步骤六 3.代码实现挖坑法 4.分析 四.字符串转整数 1.字符串方法 2.字符…

【C++重点语法下】可变参数模板,STL里面的push_back和emplace_back区别 ,包装器function,bind

目录 1.可变参数模板 1.1取出参数包内的参数方法一&#xff1a; 1.2取出参数包内的参数方法二&#xff1a; 1.3STL里面的push_back和emplace_back区别 2.包装器function 2.1function&#xff08;头文件functional&#xff09; 2.1.1可调用类型和包装器 2.1.2类的成员函数…

实验十 符号计算基础与符号微积分(matlab)

目录 实验十 符号计算基础与符号微积分 1.1实验目的 1.3流程图 1.4程序清单 1.5运行结果及分析 1.6实验的收获与体会 1.1实验目的 1.2实验内容 符号计算基础与符号微积分 课本第372页 1.3流程图 1.4程序清单 实验十 1 clear xsym(6); ysym(5); z(1x)/(sqrt(…

第9章 登录页面的跳转实现

1 “swg-login.html”登录按钮不能触发异常 由于.Net框架默认支持“HTTPS”协议从而导致“swg-login.html”登录按钮不能触发&#xff0c;其异常信息如下&#xff1a;“Mixed Content: The page at https://localhost:7037/swg-login.html was loaded over HTTPS, but requeste…

FinalShell软件连接成功后,root文件夹显示一直加载中....

出现这样的问题就是因为我们一开始进入的用户是普通用户&#xff0c;然后你就会想着使用su命令转为超级用户&#xff0c;但是这样式不可行的&#xff0c;因为虚拟机会默认你第一次进入的用户是当前用户&#xff0c;还是解决不了问题。 解决办法&#xff1a; 再开一个连接进入…

java基于springboot_vue的校园闲置物品交易系统-计算机毕业设计

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven 本文从管理员、用户的功能要求…

Java(八)----多线程(二)

1. 生产者与消费者 1.1 安全问题产生 线程本身就是一个新创建的方法栈内存 (CPU进来读取数据) 线程的notify(),唤醒第一个等待的线程 解决办法 : 全部唤醒 notifyAll() 被唤醒线程,已经进行过if判断,一旦醒来继续执行 线程被唤醒后,不能立刻就执行,再次判断标志位,利用循环 …

[附源码]Python计算机毕业设计Django基于Vue的社区拼购商城

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Python学习日记-第三十八天-生成器

系列文章目录 生成器创建生成器的方法生成器-使用send方式唤醒使用yield完成多任务一、生成器 利用迭代器&#xff0c;我们可以在每次迭代获取数据&#xff08;通过next方法&#xff09;时按照特定的规律进行生成&#xff0c;但是我们在实现一个迭代器时&#xff0c;关于当前…

Pr:导出设置之基本视频设置

视频 VIDEO设置因所选导出格式而异。每种格式都有独特的要求&#xff0c;这些要求决定了哪些设置可用。以导出文件格式为 H.264 为例&#xff0c;下面给出有关基本视频设置 Basic Video Settings的选项及说明。匹配源Match Souce自动设定视频设置选项以匹配源视频的属性。支持匹…

项目一共30个模块,你叫我maven版本一个个手动改?

之前有个群友私聊问我&#xff0c;如何快速统一去更改项目中所有的maven版本号&#xff0c;他说之前都是手动一个个去修改&#xff0c;项目一共有30多个maven模块&#xff0c;上次因为漏改了一个&#xff0c;还造成了生产事故。 其实我自己开源项目有的工程也非常多&#xff0…

Java入门必备知识你能掌握多少?

1、Java是一种高级计算机语言&#xff0c;是可以编写跨平台应用软件、完全面向对象的程序设计语言。 2、Java划分为三个技术平台&#xff1a;Java SE、Java EE、Java ME Java SE是桌面应用&#xff0c;Java EE是web应用&#xff0c;平台企业版&#xff0c;Java ME是手机应用&…