第一次写博客,记录下工作中的心得
Token与Session的区别
在介绍如何创建token之前,首先需要介绍一下token与seesion的区别,以下的描述我会尽量用大白话,方便自己和看到这篇文章的朋友更容易理解!
Session工作原理
工作原理:
- 客户端发送请求到服务端;
- 服务端验证信息后,将登陆信息记录到session中,此时的session是放在服务端的内存中;
- 服务端处理完业务后,将session对应的一个特殊cookie返回客户端;
- 客户端下次请求会携带cookie到服务端,根据cookie获取session;
- 每添加一个用户,就会在服务端保存一个seesion,这就导致服务端的压力变大,同时,由于session是保存内存中的,导致如果需要负载服务端,就需要布置一个中间件,例如redis帮助管理session;
token工作原理
工作原理:
- 客户端发送请求到服务端;
- 服务端检查header中是否携带符合要求的token,例如以Bearer开头 ;
- 服务端处理解析token,如果token信息校验通过,则会处理业务;
- token是保存在客户端的,每次请求都必须携带token,因此对于分布式部署的登录尤其适合,同时在大量客户存在时,服务器端的压力也会减少。
Token的创建
token由三部分组成,包括header(头部)、payload(载荷)、signature(签证)
header
包含两个信息alg(加密算法名称)、typ(JWT)
Map<String,Object> headMap=new HashMap<>();
headMap.put("alg","算法名称");
headMap.put("typ","JWT");
Jwts.builder().setHeader(headMap);
payload
承载一些需要传递的参数,包含三个部分
标准中注册的声明
- iss: jwt签发者
- sub: jwt所面向的用户
- aud: 接收jwt的一方
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- nbf: 定义在什么时间之前,该jwt都是不可用的.
- iat: jwt的签发时间
- jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
公共的声明
主要放一些我们需要给到前端的信息,但是一些敏感信息不建议放进去,因为这部分是可以被前端解码的;
私有的声明
这部分信息是提供者和消费者共同定义的,因为这部分信息是base64可以对称解码的,相当于明文,所以敏感信息不建议放入这里
代码
生成token
/**设置头部、载荷、签证*/
JwtBuilder builder = Jwts.builder().setHeader(headMap)
.claim("userName", userName)
.signWith(signatureAlgorithm, signingKey);
/**token过期时间*/
builder.setExpiration(expDate).setNotBefore(now);
/**token编码*/
builder.compact();
解析token
/**设置签证的自定义盐,然后将前端传入的token解析,并获取公共的声明部分,之后只要自己去校验业务方便信息就可以了*/
Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary('自定义盐'))
.parseClaimsJws(jsonWebToken).getBody();