发表于: 2019-11-16 23:50:40

1 959


今天完成的事:
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。

返回列表 返回列表
评论

    分享到