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("用户名或密码错误!");
	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于Spring Boot集成JWT实现登录的步骤,可以按照以下几个步骤进行操作: 1. 添加依赖:在`pom.xml`文件中添加以下依赖,以引入JWT相关的库: ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> ``` 2. 创建JWT工具类:创建一个JWT工具类,用于生成和解析JWT。你可以使用`Jwts.builder()`来创建JWT,并设置相关的声明(例如,用户ID、角色等)和过期时间。 3. 创建登录接口:创建一个登录接口,用于验证用户名和密码,并生成相应的JWT。在验证通过后,可以使用JWT工具类生成JWT并返回给客户端。 4. 配置Spring Security:为了保护你的API,你需要进行Spring Security的配置。你可以创建一个继承`WebSecurityConfigurerAdapter`的类,并重写`configure()`方法来配置安全规则。在这个方法中,你可以配置哪些URL需要进行认证,哪些URL不需要认证(例如,登录接口)。 5. 创建Token过滤器:创建一个Token过滤器,用于验证请求中的JWT,并将用户信息存储到SecurityContext中,以便在后续的请求中使用。 6. 配置Token过滤器:在Spring Security配置类中,将Token过滤器添加到过滤器链中,以保证每个请求都会经过Token过滤器的验证。 通过以上步骤,你就可以实现Spring Boot集成JWT实现登录功能。当用户登录成功后,会生成一个JWT,并在后续的请求中使用该JWT进行身份验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值