美文网首页app token
Token生成规则以及工具

Token生成规则以及工具

作者: Frankeen | 来源:发表于2018-01-17 16:29 被阅读1032次
Token工具
package com.frank.common.utils;

import com.alibaba.fastjson.JSON;
import com.frank.common.entity.TokenHeader;
import com.frank.common.entity.TokenPlayload;
import com.frank.common.entity.User;

import java.rmi.server.UID;
import java.util.UUID;

/**
 * Description:Token生成工具
 * 第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).
 * Auth: Frank
 * Date: 2017-11-02
 * Time: 下午 5:05
 */
public class TokenUtil {
    public static final  String TOKEN_AES_KEY = "xiangli8Token";
    public static final  String REFREH_TOKEN_AES_KEY = "xiangli8RefreshToken";
    public static final  String JWT_TYP = "JWT";
    public static final  String JWT_ALG = "AES";
    public static final  String JWT_EXP = "30";
    public static final  String JWT_ISS = "xiangli8";

    /**
     * 获得token
     * @param data 自定义数据
     * @param <T> 自定义数据
     * @return
     * @throws Exception
     */
    public static <T> String getToken(T data) throws Exception {
        TokenPlayload<T> userTokenPlayload = new TokenPlayload<>();
        userTokenPlayload.setExpData(data);
        String jwt = createJWT(userTokenPlayload);
        return jwt;
    }

    /**
     * 生成jwt的header部分内容
     * @return
     * @throws Exception
     */
    private static String tokenHeaderBase64() throws Exception {
        TokenHeader tokenHeader = new TokenHeader();
        tokenHeader.setTyp(JWT_TYP);
        tokenHeader.setAlg(JWT_ALG);

        String headerJson = JSON.toJSONString(tokenHeader);

        String headerBase64 = Base64Util.encryptBASE64(headerJson.getBytes());

        return headerBase64;
    }

    /**
     * 生成jwt的payload部分内容
     * @param tokenPlayload
     * @param <T>自定义的数据块
     * @return
     * @throws Exception
     */
    private static <T> String tokenPayloadBase64(TokenPlayload<T> tokenPlayload) throws Exception {
        tokenPlayload.setIss(JWT_ISS);
        tokenPlayload.setExp(JWT_EXP);

        tokenPlayload.setIat(String.valueOf(System.currentTimeMillis()));

        String headerJson =JSON.toJSONString(tokenPlayload);

        String headerBase64 = Base64Util.encryptBASE64(headerJson.getBytes());

        return headerBase64;
    }

    /**
     * 生成JWT
     * @return
     */
    public static <T> String createJWT(TokenPlayload<T> tokenPlayload) throws Exception {
        StringBuilder jwtSb = new StringBuilder();
        StringBuilder headerPlayloadSb = new StringBuilder();

        String tokenHeaderBase64 = tokenHeaderBase64();
        String tokenPayloadBase64 = tokenPayloadBase64(tokenPlayload);

        jwtSb.append(tokenHeaderBase64);
        jwtSb.append(".");
        jwtSb.append(tokenPayloadBase64);
        jwtSb.append(".");

        headerPlayloadSb.append(tokenHeaderBase64);
        headerPlayloadSb.append(tokenPayloadBase64);

        String headerPlayloadSalt = SaltUtil.addSalt(headerPlayloadSb.toString());

        String key = AesUtil.initKey(TOKEN_AES_KEY+tokenPlayload.getIat());

        String  signature = Base64Util.encryptBASE64(AesUtil.encrypt(headerPlayloadSalt.getBytes(),key));

        jwtSb.append(signature);

        return Base64Util.encryptBASE64(jwtSb.toString().getBytes());
    }

    /**
     * 校验token是否是服务器生成的,以防token被修改
     * @param jwtBase64
     * @return
     * @throws Exception
     */
    public static <T> boolean verifyJWT(String jwtBase64) throws Exception {
        String jwt = new String (Base64Util.decryptBASE64(jwtBase64));

        if(!jwt.contains(".")){
            return false;
        }

        String[] jwts = jwt.split("\\.");
        if(jwts.length<3){
            return false;
        }

        TokenPlayload tTokenPlayload =  JSON.parseObject(new String(Base64Util.decryptBASE64(jwts[1])),TokenPlayload.class);
        String key = AesUtil.initKey(TOKEN_AES_KEY+tTokenPlayload.getIat());

        //解析出header跟playload
        StringBuilder headerPlayloadSb = new StringBuilder();
        headerPlayloadSb.append(jwts[0]);
        headerPlayloadSb.append(jwts[1]);

        //解析signature
        String  headerPlayloadSalt = new String (AesUtil.decrypt(Base64Util.decryptBASE64(jwts[2]),key));

        return SaltUtil.verifyPwd(headerPlayloadSb.toString(),headerPlayloadSalt);
    }

    /**
     * 生成refreshToken
     * @return
     */
    public static String createRefreshToken(String jwt) throws Exception {
        StringBuilder seedSb = new StringBuilder();
        seedSb.append(TOKEN_AES_KEY).append(jwt).append(UUID.randomUUID());
        String key = AesUtil.initKey(seedSb.toString());
        String  refreshToken = Base64Util.encryptBASE64(AesUtil.encrypt(jwt.getBytes(),key));
        return refreshToken;
    }

    public static void main(String[] args) throws Exception {
        String jwt = getToken(new User(1L,"你是逗逼"));
        System.out.println("jwt:"+jwt);
        System.out.println("verifyJWT:"+verifyJWT(jwt));
    }
}

使用说明

1,根据上面生成一个由base64编码的token,该token由Header,Payload,Signature组成。

2,token作为用户请求的标识,客户端保存这token的全部信息。服务端只需要保存token的Signature部分。

3,服务端把token的Signature存于redis和服务器的数据库中。

4,客户端请求的数据附带token,服务端拿到token,首先校验token,以防token伪造。校验规则如下:

4.1,拆分出token的Header,Payload,Signature。
4.2,校验Signature,通过token的header和payload生成Signature,看看生成的Signature是否和客户端附带上来的Signature一致。如果一致继续请求操作,不一致则打回操作
4.3,查看Signature是否存在服务器的redis和数据库中。如果不存在则打回请求操作

相关文章

  • Token生成规则以及工具

    Token工具 使用说明 1,根据上面生成一个由base64编码的token,该token由Header,Payl...

  • springboot+shiro+jwt

    JWTUtil 我们利用 JWT 的工具类来生成我们的 token,这个工具类主要有生成 token 和 校验 t...

  • 微信开发中access_token,js_ticket,时间戳,

    1. Access_token生成工具 工具地址:https://mp.weixin.qq.com/debug ...

  • jwt 在微服务中应用

    jwt token jwt 在api 方式中表中的token生成,验证以及获取jwt解密后携带的用户信息 jwt ...

  • 微信公众号----创建菜单

    创建菜单我们可以使用微信提供的工具进行生成 如何获取access_token每次获取的access_token有效...

  • 生成Token的工具类

    package xdp.gacl.session;import java.security.MessageDige...

  • Find_Sec_Bugs检测项

    1、不安全的随机数生成,在CSRF TOKEN生成、password reset token生成等,会造成toke...

  • Java连接influxDB

    influxDB 版本 2.0 java连接influxDB 生成Token图片.png 生成token时可选择读...

  • Java-token

    token基础 生成token 解析token 问题 : 在退出登录 / 修改密码时怎样实现JWT Token失效...

  • [原创] Cmake初体验

    Cmake是什么 cmake是一种自动生成makefile规则的工具,它有一套自己的语法规则来指导生成整个项目源码...

网友评论

    本文标题:Token生成规则以及工具

    本文链接:https://www.haomeiwen.com/subject/yueuoxtx.html