JWT的一个实现

使用经历

前段时间做Android后台Rest接口开发时,需要验证客户端的身份信息所以进行了学习。今天正好有人问到了博主关于JWT的使用所以就在这里记录下JWT的一个使用场景。

话不多说直接上源码

Token.java(token类)

import lombok.Data;

@Data
public class Token {
    private Integer userId;
    private String email;

    public Token() {
    }

    public Token(Integer userId, String email) {
        this.userId = userId;
        this.email = email;
    }
}

JWT.java(JWT的工具类)

import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.internal.com.fasterxml.jackson.databind.ObjectMapper;
//token实体
import com.lee.yantu.Entity.Token;
//用户实体
import com.lee.yantu.Entity.User;
//这是自己写的异常枚举类
import com.lee.yantu.enums.SystemEnum;
import com.lee.yantu.exception.ResultException;

import java.util.HashMap;
import java.util.Map;

public class JWT {
    //这是服务端的token密码,用于加密token
    private static final String SECRET = "@#$@#$@#";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    /**
     * 私有方法,对传入的实体进行加密,并设置日期
     *
     * @param object the POJO object
     * @param maxAge the milliseconds of life time
     * @return the jwt token
     */
    private static <T> String sign(T object, long maxAge) {
        try {
            final JWTSigner signer = new JWTSigner(SECRET);
            final Map<String, Object> claims = new HashMap<String, Object>();
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(object);
            claims.put(PAYLOAD, jsonString);
            claims.put(EXP, System.currentTimeMillis() + maxAge);
            return signer.sign(claims);
        } catch (Exception e) {
            throw new ResultException(SystemEnum.UNKNOWN_ERROR);
        }
    }



    /**
     * 解密token验证token的正确性
     *
     * @param jwt
     * @return POJO object
     */
    private static <T> T unsign(String jwt, Class<T> classT) {
        //解密token
        final JWTVerifier verifier = new JWTVerifier(SECRET);
        try {
            final Map<String, Object> claims = verifier.verify(jwt);
            if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
                //获取过期时间
                long exp = (Long) claims.get(EXP);
                //获取系统时间
                long currentTimeMillis = System.currentTimeMillis();
                System.out.println("exp:"+exp+"  now:"+currentTimeMillis);
                if (exp > currentTimeMillis) {
                    String json = (String) claims.get(PAYLOAD);
                    ObjectMapper objectMapper = new ObjectMapper();
                    return objectMapper.readValue(json, classT);
                }else throw new ResultException(SystemEnum.TOKEN_EXP);
            }else throw new ResultException(SystemEnum.TOKEN_ERR);
        } catch (Exception e) {
            throw new ResultException(SystemEnum.TOKEN_ERR);
        }
    }

    /**
     * 获取加密后的token
     * @param user
     * @return
     */
    public static String getTokenString(User user){
        Token token = new Token();
        token.setUserId(user.getUserId());
        token.setEmail(user.getEmail());
        return sign(token,1*60*60*1000L); //设置过期时间默认1小时
    }

    /**
     * 获取加密后的token,可以自己定义过期时间
     * @param user
     * @param time
     * @return
     */
    public static String getTokenString(User user,Long time){
        Token token = new Token();
        token.setUserId(user.getUserId());
        token.setEmail(user.getEmail());
        return sign(token,time);
    }

    /**
     * 获取解密后的token
     * @return
     */
    public static Token getTokenInstance(String token){
        return unsign(token,Token.class);
    }
}

注意事项

注:token返回时是作为一个String类型

  1. 通过String token = JWT.getTokenString(user);获取token
  2. 通过JWT.getTokenInstance(token);验证token
  3. token根据业务需求自己决定存储方式(我是保存在客户端)
  4. 客户端登录或着注册之后拿到属于自己的token并保存
  5. 之后每次进行操作时提交token,后端获取token并进行验证

版权声明: 本文由Lee创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处
本文链接:http://leewant.github.io/2018/07/09/JWT的一个实现/