什么是token?

        token我们可以理解为一个令牌,主要的作用是守护我们系统的安全,像我们登录这些都是可以使用token进行用户数据校验的,那么为什么不用传统的session呢?主要还是session是前端页面生成给我们的,当某一个窗口关闭了以后或者session发生了变化那么在请求服务就歇菜了,session的主动权在与前端,而token的主动权者在于服务端。

那么我们如何实现呢?看下面的代码吧!

<!--导入下面依赖吧-->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.3.0</version>
</dependency>

生成token

    //设置过期时间(毫秒为单位)
    private static final long EXPIRE_DATE=1*60*1000;
    //token秘钥(可以自定义一个随机字符串就行,避免中文)
    private static final String TOKEN_SECRET = "ZCEQIUBFKSJBFJH2020BQWE";
    /**
     * 
     * @param username  传入用户名
     * @param password  传入密码
     * @return
     */
    @GetMapping("/getToken")
    public String getToken(String username, String password) {
        String token = "";
        try {
            //过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //设置头部信息
            Map<String, Object> header = new HashMap<>();
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            //携带username,password和用户ID信息,生成签名,按照需求而定
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("username", username).withClaim("userId", 用户id)
                    .withClaim("password", password).withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return token;
    }

校验token是否过期

  /**
     * 校验Token是否过期
     * @param token
     * @return
     */
    public static boolean verifyToken(String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }

解析token信息

   /**
     * 解析Token
     * @param key     需要解析的key字符串(username、userId等等,就是携带数据生成token的Key)
     * @param token   传入token
     * @return
     */
    public static String getUsername(String token,String key){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        }catch (JWTDecodeException e){
            e.printStackTrace();
        }
        return null;
    }

可能很多人直接使用上面的代码进行登录接口实现了,那么同志们有想过一个问题吗?上面设置了token的过期时间的,当用户正在使用我们软件的时候,突然token过期了直接报了个401,这个时候用户肯定是一脸懵逼了,有很多软件都会出现这个问题,就是因为偷懒了,我们不经常发现是因为他们的token设置的过期时间较长而已。我下面给大家提供了解决方案。

1、后台可以在生成token返回给前端的时候缓存一下token,比如我们token过期时间是30分钟,那么我们缓存有效期就设置10分钟就行了,前端每次请求都刷新我们的缓存,如果前端10分钟都没有请求的话我们的token就自动过期了,如果我们的缓存token没过期但是实际token过期了怎么办呢?这个时候我们就可以直接生成一个新的token返回给前端。

2、生成token的时候生成两个token返回给前端(假如生成了A和B两个token)A的Token返回给前端用作数据交互,B的Token用来刷新A的Token,这个时候我们就可以将B设置过期时间长一点,当后台发现A过期的话返回401给前端,前端在使用B来换取新的token,我们后台收到换取token通知的时候将原来A里面的数据解析出来重新使用数据生成一个新的token返回给前端。

温馨提示一下 : 我们在生成token的时候需要注意要防止别人去里面解析数据,最好对token进行数据的加密处理。比如有的同学使用账号密码生成token,这种方法要特别注意。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。