JWT(JSON Web Token)原理详细解析

一、JWT(单点登录)

        JSON Web Token(JWT),全称是Json Web Token, 是JSON风格轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权;它是分布式服务权限控制的标准解决方案!

二、为什么使用jwt

       目前企业开发基于前后端分离,session已不能满足需求,需要使用JWT。
来看下面这张图,更加方便你理解。

 三、JWT使用过程

     此处对于用户密码做了SHA-256+盐加密,用于与shiro权限管理结合做铺垫。

 

   1)前端通过表单将用户名和密码发送到后端接口。

   2)后端核对用户名和密码后,将用户的id及其他非敏感信息作为JWT Payload,将其与头部分别进行base64编码后签名,生成JWT

public static String createJWT(User user) {
		logger.debug("-------------------生成token-----------------------");
		//加密算法
		SignatureAlgorithm hs256 = SignatureAlgorithm.HS256;
		//当前日期
		long currentTimeMillis = System.currentTimeMillis();
		Date date = new Date(currentTimeMillis);
		//获取私钥
		SecretKey secretKey=getKey();
		//秘密,用于储存用户信息
		HashMap<String, Object> claims = new HashMap<>();
		claims.put(user.getUserName(), user.getUserName());
		claims.put(user.getPassword(), user.getPassword());
		//创建JET的构造器,指定加密算法,生成token
		JwtBuilder builder = Jwts.builder()
				//唯一标识
				.setId(user.getUuid())
				//签发者
				.setIssuer(user.getUserName())
				.setSubject(user.getUserName())
				//生效时间
				.setIssuedAt(date)
				//设定私钥和算法
				.signWith(hs256, secretKey)
				//Claim储存用户账户密码
				.addClaims(claims)
				//唯一标识
				.setAudience(user.getUuid());
		//设置有效时间
		if (currentTimeMillis >= 0) {
			long expMillis=currentTimeMillis + 60*1000*15;
			Date newDate = new Date(expMillis);
			builder.setExpiration(newDate);
		}
		return builder.compact();

	}

  3)后端将JWT字符串作为登录成功的结果返回给前端,前端可以将JWT存到localStorage或者sessionStorage中,退出登录时,前端删除保存的JWT信息即可。

  4)前端每次在请求时,将JWT放到header中的Authorization,但我边通过session+redis完成token储存

request.getSession().setAttribute("uuid", newUsers.getUuid());
//session声明周期
request.getSession().setMaxInactiveInterval(24*60*60);
//存入redis
redisUtil.save(newUsers.getUuid(), token);
redisUtil.setSaveTime(newUsers.getUuid(), 15*60);

  5)每次请求接口,后端验证JWT的有效性,时效性,同时刷新token

//用户存在验证token(核实)
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(JWTUtil.JWT_SECERT)).build();
try {
					
	//使用生成token配置选项对给定令牌执行验证。
	DecodedJWT verify = jwtVerifier.verify(token);
	if (!verify.getToken().equals(token)) {
		throw new MyException(ErrorCode.USER_EXIST, "token验证失败,请重新登录");
	 }
	//刷新token
	String newToken = JWTUtil.createJWT(newUser);
	if (!ObjectUtils.isEmpty(newToken)) {
			redisUtil.save(uuid, newToken);
			redisUtil.setSaveTime(uuid, 15*60);
	}
  } catch (Exception e) {
    	throw new MyException(ErrorCode.USER_EXIST, "token验证失败,请重新登录");
	}

 

  6)验证通过后,进行其他逻辑操作。

四、测试数据结果分析

 

JWT的token包含三部分数据:

Header:头部,通常头部有两部分信息:

声明类型type,这里是JWT(type=jwt)

加密算法,这里采用SHA-256+加盐加密

我们会对头部进行base64加密(可解密),得到第一部分数据

Payload:载荷,就是有效数据,一般包含下面信息:

用户身份信息-userid,username(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息)

注册声明:如token的签发时间,过期时间,签发人等

这部分也会采用base64加密,得到第二部分数据

Signature:base64加密,签名,是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret,盐)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和安全可靠性

 

参考文献:JWT认证原理及使用

                 JWT详解
                JWT原理解析

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值