山东大学软件工程项目实训_lwt(2021-4)(2)

山东大学软件工程项目实训(2021-4)

发现用户安全问题,需要token工具类,进行token代码开发和拦截器过滤器开发

一、本阶段工作进展

1.学习jwt构建token工具类

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
在这里插入图片描述

  1. 用户使用账号和面发出post请求;
  2. 服务器使用私钥创建一个jwt;
  3. 服务器返回这个jwt给浏览器;
  4. 浏览器将该jwt串在请求头中像服务器发送请求;
  5. 服务器验证该jwt;
  6. 返回响应的资源给浏览器。
2.实现create/check/refresh token相关函数
2.1 目标

该工具类主要为实现User类的信息加密存储,传输。
对登录的用户进行验证,生成带有id信息的唯一加密的token,用于前后端传输。

public class User {
    private Long id;        	//用户id
    private String username;   //用户名
    private String password;   //用户密码
    private String name;       //用户姓名
    private Integer post;       //用户职务
}
2.2 测试

测试程序(忽略优化输出格式的代码)

 /** test tokenUtil **/
        /**     create user **/
        User user = new User();
        user.setId(123l);
        user.setName("testToken");
        user.setUsername("taoTest");
        user.setPassword("123testToken");
        user.setPost(2);
        System.out.println("|--usr info:\t\t\t"+user.getId());
        /**     test createToken() **/
        String token = TokenUtil.createToken(user);
        System.out.println("|--token: \t\t\t"+token);
        /**     test decodeToken() **/
        long res = TokenUtil.decodeToken(token);
        System.out.println("|--res from decodeToken():\t\t\t"+res);
        /**     test refreshToken() **/
        String newToken1 = TokenUtil.refreshToken(token);
        System.out.println("|--newToken1: \t\t\t"+newToken1);
        TokenUtil.tokenExpireTime = 1;
        String token2 = TokenUtil.createToken(user);
        System.out.println("|--wait...");
        TimeUnit.MINUTES.sleep(1);//分
        String newToken2 = TokenUtil.refreshToken(token2);
        System.out.println("|--newToken2: \t\t\t"+newToken2);

测试结果(成功实现相关功能)
在这里插入图片描述

二、程序具体实现与解读

1. 相关设置
	private static Integer tokenExpireTime = 10; //token过期时间,单位分钟
    private static String secretKey = "XXXXXXXXXXXX"; // 固定的服务器私钥
2. 生成token

根据user的id和服务器的密钥生成唯一加密的token。

输入输出
User类对象String类型token
public static String createToken(User user) {
        // id + JWT私钥加密
        String secret = secretKey + user.getId();
        // 过期时间,单位:毫秒
        long expireTime = System.currentTimeMillis() + tokenExpireTime*60*1000L;
        // 将 userId + currentTime 保存到 token 里面; 以 secret 作为 token 的密钥
        String token= JWT.create().withAudience(user.getId() +";;"+ expireTime)
                .sign(Algorithm.HMAC256(secret));
        return token;
    }
2. 解读token

根据token获取其中的userId。

输入输出
String类型tokenlong类型userId
public static long decodeToken(String token) {
        // 判null
        if (token == null) {
            throw new RuntimeException("Error: token is null in decodeToken ");
        }
        // 获取 token 中的 user id
        String content;
        try {
            content = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            throw new RuntimeException("401 (jwt decode error)");
        }
        long userId = Long.parseLong(content.split(";;")[0]);
        return userId;
    }
3. 刷新token

根据token获取其中的过期时间判断是否进行刷新操作。

输入输出1输出2
String类型token原token(未过期)新token(过期)
public static String refreshToken(String token) {
        //根据有效期检查是否需要更新Token
        if (token != null){
            String content;
            try {
                content = JWT.decode(token).getAudience().get(0);

            } catch (JWTDecodeException j) {
                throw new RuntimeException("401 (jwt decode error)");
            }

            long expireTime = Long.parseLong(content.split(";;")[1]);
            long currentTime = System.currentTimeMillis();
            long userIdToken = Long.parseLong(content.split(";;")[0]);

            if (currentTime > expireTime){
                // 已失效
                String secret = secretKey + userIdToken;
                long newExpireTime = System.currentTimeMillis() + tokenExpireTime*60*1000L;
                String newToken= JWT.create().withAudience(userIdToken +";;"+ expireTime)
                        .sign(Algorithm.HMAC256(secret));
                return newToken;
            }
        }else {
            throw new RuntimeException("Error: token is null in refreshToken ");
        }
        return token;
    }

暂时未用的验证 token

//    public static Boolean checkToken(String token) {
//        // 判null
//        if (token == null) {
//            throw new RuntimeException("Error: token is null in checkToken ");
//        }
//        // 获取 token 中的 user id
//        String content;
//        try {
//            content = JWT.decode(token).getAudience().get(0);
//
//        } catch (JWTDecodeException j) {
//            throw new RuntimeException("401 (jwt decode error)");
//        }
//        long userId = Long.parseLong(content.split(";;")[0]);
//        User user = userMapper.selectOne(userId);
//        if (user == null) {
//            throw new RuntimeException("用户不存在,请重新登录");
//        }
//        // 验证 token     如果验证失败应该返回FALSE???
//        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
//        try {
//            jwtVerifier.verify(token);
//        } catch (JWTVerificationException e) {
//            throw new RuntimeException("401 (jwt verify error)");
//        }
//        return true;
//    }

三、下一阶段工作目标

实现拦截器,联系前端进行调试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值