我是靠谱客的博主 无奈大神,最近开发中收集的这篇文章主要介绍SpringBoot集合JWT实现工具类,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 一、JWT是什么
    • 二、JWT构成
    • 三、SpringBoot集成JWT

一、JWT是什么

什么是JWT:Json web token (JWT) 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA或ECDSA的公私秘钥对进行签名。

JWT如何获取访问令牌(token)并用于访问资源(API)流程:1、应用端向权限服务器请求授权;2、权限服务器授权成功向应用端返回一个访问令牌(token);3、应用端使用访问令牌(token)访问受保护的资源(如API)。

在这里插入图片描述

二、JWT构成

2.1	JWT是由三段信息构成,将这三段信息文本用“.“连接一起就构成了JWT字符串,一个 Token 分三部分,按顺序为
	1.头部(header)
	2.载荷(payload)
	3.签证(signature)
	例如:`eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1NTgwNjI2OTYsInVzZXJJZCI6IjEifQ.XiI0xjX0izVeJRmhbXN1w1fXKdHB0wsc9teFKq84pclpJt6yS2k0BVXAklHrke_nz6XtcCyi1hgvpn8bf95gwg`。

2.2  header
	JWT的头部承载两部分信息:
		1.声明类型,这里是JWT
		2.声明加密的算法,通常直接使用 HMAC SHA256
		JWT里验证和签名使用的算法列表如下:
JWT算法名称
HS256HMAC256
HS384HMAC384
HS512HMAC512
RS256RSA256
RS384RSA384
RS512RSA512
ES256ECDSA256
ES384ECDSA384
ES512ECDSA512
2.3 playload
	载荷就是存放有效信息的地方。基本上填两种类型的数据
		1.标准中注册的声明的数据;
		2.自定义数据;
		由这两部分内部做 base64 加密。
		标准中注册的声明(建议但不强制使用)
		iss: jwt签发者
		sub: jwt所面向的用户
		aud: 接收jwt的一方
		exp: jwt的过期时间,这个过期时间必须要大于签发时间
		nbf: 定义在什么时间之前,该jwt都是不可用的.
		iat: jwt的签发时间
		jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
	
		自定义数据:存放我们想放在 token 中存放的 key-value 值;
2.4 signature
	JWT的第三部分是一个签证信息,这个签证信息由三部分组成;
	base64 加密后的 header 和 base64 加密后的 payload 连接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了JWT的第三部分

三、SpringBoot集成JWT

3.1 添加依赖:

<!-- jwt核心源码库 -->
		<dependency>
			<groupId>com.auth0</groupId>
			<artifactId>java-jwt</artifactId>
			<version>3.3.0</version>
		</dependency>
		<!-- java开发jwt的依赖jar包 -->
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.9.0</version>
		</dependency>

3.2 创建常量类:

public interface Constants {

	/************ utils-jwt ************/

	/* jwt密钥的key基数 */
	public static String JWT_SECERT = "SSO_JWT_SECERT_KEY";
	
	/* 签发者 */
	public static String JWT_ISS_USER = "sxt-frugal-jwt";
	
	/* token认证错误 */
	public static int JWT_FAILED_CODE = 500;
	
	/* token超时 */
	public static int JWT_EXPIRE_CODE = 504;
	
	/* jwt持续时间 */
	public static int JWT_LOGIN_MILLIS = 10 * 60 * 1000;
	
	/* jwt添加head头key */
	public static String JWT_HEAD_KEY = "Authorization";
	
	/* MD5加密 盐粒 */
	public static String PASSWORD_KEY = "password_salt_key";
	
	/************ sso-login ************/
	/* 登陆时间限制(单位:秒) */
	public static int SSO_LOGIN_SECOND = 60 * 30;
}

3.3 创建工具类

@Slf4j
public class JWTUtils {

	public static final ObjectMapper mapper = new ObjectMapper();

	/**
	 * 生成jwt密钥key
	 * 
	 * @param algorithm
	 * @return
	 */
	private static SecretKey generalKey(String algorithm) {
		byte[] secreKey = Base64.decode(Constants.JWT_SECERT);
		return new SecretKeySpec(secreKey, 0, secreKey.length, algorithm);
	}

	/**
	 * 生成token
	 * 
	 * @param id        jwt唯一标识,主要作为一次性token,避免重放攻击
	 * @param iss       jwt签发者
	 * @param claims    payload中的公开信息一般为用户名
	 * @param ttlmillis 有效期,单位毫秒
	 * @return token 一次性token,客户端的有效周期,用户退出或者超时,token失效
	 */
	public static String createJwt(String id, String iss, String claims, long ttlmillis) {
		SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
		long timeMillis = System.currentTimeMillis();
		Date curDate = new Date(timeMillis);
		JwtBuilder jwtBuilder = Jwts.builder().setId(id).setIssuer(iss).setSubject(claims)
				/* 设置签发时间 */
				.setIssuedAt(curDate)
				/* 设置密钥和算法 */
				.signWith(algorithm, JWTUtils.generalKey("AES"));
		if (ttlmillis > 0) {
			/* 设置token失效时间 */
			jwtBuilder.setExpiration(new Date(ttlmillis + timeMillis));
		}
		return jwtBuilder.compact();
	}

	/**
	 * jwt认证
	 * 
	 * @param token
	 * @return
	 */
	public static JwtEntity validateToken(String token) {
		JwtEntity jwtEntity = new JwtEntity();
		Claims claims = null;
		try {
			claims = JWTUtils.parseToken(token);
			jwtEntity.setStatus(true);
			jwtEntity.setClaims(claims);
		} catch (Exception e) {
			log.error("jwt解析异常:", e);
			jwtEntity.setStatus(false);
			jwtEntity.setCode(Constants.JWT_FAILED_CODE);
		}
		return jwtEntity;
	}

	/**
	 * 解析token
	 * 
	 * @param token 服务器给客户端的token
	 * @return
	 */
	private static Claims parseToken(String token) {
		SecretKey generaKey = JWTUtils.generalKey("AES");
		return Jwts.parser().setSigningKey(generaKey).parseClaimsJwt(token).getBody();
	}

	/**
	 * 生成subject对象
	 * 
	 * @param object
	 * @return
	 * @throws JsonProcessingException
	 */
	public static String generalSubject(Object object) throws JsonProcessingException {
		return mapper.writeValueAsString(object);
	}

	/**
	 * 重新生成jwt
	 * 
	 * @param jwtEntity
	 * @return
	 */
	public static String reInitJwt(JwtEntity jwtEntity) {
		Claims claims = jwtEntity.getClaims();
		return JWTUtils.createJwt(String.valueOf(System.nanoTime()), Constants.JWT_ISS_USER, claims.getSubject(),
				Constants.JWT_LOGIN_MILLIS);
	}

3.4 JWT工具类调用

public ResponseEntity getLogin(String phone, String password) {
		Map<String, String> login = loginMapper.selectOne(phone);
		if (MapUtil.isEmpty(login)) {
			return ResponseEnum.FAILED.fail("该用户不存在!");
		}
		String mdPwd = new HmacUtils(HmacAlgorithms.HMAC_MD5, Constants.PASSWORD_KEY).hmacHex(password);
		/* 判断密码是否相同 */
		if (mdPwd.equals(login.get("password"))) {
			login.remove("password");
			String claims = null;
			try {
				claims = JWTUtils.generalSubject(login);
			} catch (JsonProcessingException e) {
				log.error("claims 解析json异常!", e);
				e.printStackTrace();
			}
			/* 生成jwt */
			String jwt = JWTUtils.createJwt(String.valueOf(System.nanoTime()), phone, claims,
					Constants.JWT_LOGIN_MILLIS);
			/* 添加jwt到header */
			response.addHeader(Constants.JWT_HEAD_KEY, jwt);
			/* 缓存phone */
			JedisTemplate.getInstance().setStringEx(ThreadUtils.getCurrentThreadId(), Constants.SSO_LOGIN_SECOND,  phone);
			/* 缓存用户基本信息 */
			return ResponseEnum.SUCCESSED.success(login);
		}
		return ResponseEnum.FAILED.fail("用户名或密码错误!");
	}

最后

以上就是无奈大神为你收集整理的SpringBoot集合JWT实现工具类的全部内容,希望文章能够帮你解决SpringBoot集合JWT实现工具类所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部