发表于: 2019-11-16 23:50:40
1 957
今天完成的事:
1、学习JWT、token。
token,就是一种身份验证的令牌,是一些信息的集合。
当用户登录成功后,服务器会返回一个token,浏览器使用cookie保存,在以后的每次请求中都带着这个token令牌,服务器识别后,就认为是处于登录状态。当然也可以进行其他的一些请求。
而JWT就是一种基于json的开放标准,也是一种token的格式。
JWT的token有三个部分,分别是header(头部)、payload(负载)、signature(签名),中间是使用“.”进行分隔的。
(1)header(头部)
是描述最基本的信息,类型、及签名所用算法,为json格式。如下。
(2)payload(负载)
负载也是json对象,用来传递实际需要的东西,官方定义了7个字段,也可以添加自定义私有字段。
(3)signature(签名)
签名有三个部分,先是用 base64 编码 header.payload 部分,再使用密钥进行加密,然后再和 header、payload 组合成一个JWT。这个密钥最好保存在服务器端。
JWT的特点:
(1)JWT默认是不加密的,所以不可以把秘密信息放入到JWT中,当然生成原始token后,根据自身情况进行加密也是可以的。
(2)JWT不仅用于认证,也可以用于交换信息,有效使用JWT,尽量降低服务器的查询次数。
(3)JWT本身包含认证信息,一旦泄露,任何人都可以获得该令牌的所有权限,所以为减少盗用,有效期尽可能设置短些,对于一些重要权限,使用时应该再次对用户进行认证。
(4)为安全起见,JWT应使用HTTPS协议传输。
(5)JWT的最大缺点,由于服务器不保存session状态,所以无法在使用过程中废止某个token,或更改token权限,也及时说,一旦JWT签发,在到期之前都是有效的,除非服务器部署额外的逻辑。
2、编写JWT工具类。
首先需要导入jar包,如下。
而后我是将用户id、登录时间进行des加密,加入到JWT负载的私有声明里,并设置了唯一标识、签发时间以及过期时间。
import io.jsonwebtoken.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
// 指定秘钥
private static String key = "bzisucgsidbgpsg";
// 创建JWT,expTime 为过期时间
public static String createJwt(String id,long expTime){
// 生成JWT的时间,也是登录时间
long nowTime = System.currentTimeMillis();
Date now = new Date(nowTime);
// 指定des密钥
String desKey = "adhapsoxhasgodmcisdhc";
// des 加密id
String userId = DesUtil.encryptor(id,desKey);
// des 加密登录时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
String loginTime = DesUtil.encryptor(sdf.format(now),desKey);
// 创建payload的私有声明
Map<String,Object> claims = new HashMap<>();
// 用户id、登录时间
claims.put("userId",userId);
claims.put("loginTime",loginTime);
// 为payload添加声明
JwtBuilder jwtBuilder = Jwts.builder()
// 设置私有声明
.setClaims(claims)
// JWT 的唯一标识
.setId(id)
// JWT 的签发时间
.setIssuedAt(now)
// 设置签名所用的算法和秘钥
.signWith(SignatureAlgorithm.HS256, key);
//设置过期时间
if(expTime>=0){
long expMills = nowTime + expTime;
Date exp = new Date(expMills);
jwtBuilder.setExpiration(exp);
}
// 生成JWT
return jwtBuilder.compact();
}
// 解析token,判断有效性来检验是否登录
public static Claims parseJWT(String token){
try {
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token)
.getBody();
return claims;
// 会自动判断token是否已经过期,过期则抛出该异常
}catch(ExpiredJwtException e){
// 表示 token 已过期
return null;
}
}
}
这里测试进行token的解析,获取私有声明中的用户id、登录时间,并进行解密。
过期时间这里无法测试,只能用拦截器的时候,判断浏览器中的token是否抛出ExpiredJwtException异常,即表示token已过期。
controller类中,将注册密码进行MD5加密,登录时进行相应解密,而后判断,并且登录时创建cookie,用以存放token。
但是这样,因为cookie中没有存放用户密码,之前设置的自动登录就没法实现了。。
明天计划的事:
1、学习拦截器,实现登录状态才能访问部分网页,不登录就无法访问。
2、精简代码,请师兄查看,是否能交任务。
遇到的问题:
1、学习过程中老是能看到服务器校验token,成功则返回请求数据,但是怎么校验的并没有找到,就只是判断存在token就行了吗?还是说要解析对比相应的用户id?
官网任务说是通过拦截判断token的有效性来判断用户是否登录,是指有效期吗,只要存在这个token存在,处于有效期就是在登录状态吗?
收获:
1、学习了JWT、token。JWT就是一种基于json的开放标准,也是一种token的格式。
JWT的token有三个部分,分别是header(头部)、payload(负载)、signature(签名),中间是使用“.”进行分隔的。
2、编写JWT工具类,生成JWT、解析JWT。
评论