基于JWT令牌Token校验以及java-jwt的使用

JWT

JWT , 全写JSON Web Token, 是开放的行业标准RFC7591,用来实现端到端安全验证.
简单来说, 就是通过一些算法对加密字符串和JSON对象之间进行加解密。
JWT加密JSON,保存在客户端,不需要在服务端保存会话信息。,可以应用在前后端分离的用户验证上,后端对前端输入的用户信息进行加密产生一个令牌字符串, 前端再次请求时附加此字符串,后端再使用算法解密。

  • 下列场景中使用JSON Web Token是很有用的:
    Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
    Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。
  • JWT只是一个标准
    可以通过不过的开发语言实现,包括Java,.NET, Python,Node Js, JavaScript,Perl, Ruby,Go等。
    同一种语言,不同的开发者提供了多种实现库,以Java语言为例有java-jwt、?jose4j、nimbus-jose-jwt、jjwt
  • https://jwt.io/ 这个网站提供了在线的基于不同算法的字符串和JSON对象的转换工具,同时也收集了不同语言的多种实现库。
  • JWT的构成
    Header头部: Token类型和加密算法。加密算法常见的有MD5、SHA、HMAC( Hash Message Authentication Code)。
    PayLoad负载: 存放有效信息,包括
    标准的声明,类似开发语言总的关键字。包括
    iss(Issuser) - 签发者
    sub Subject 面向主体
    aud Audience 接收方
    exp Expiration time 过期时间戳
    nbf Not Before, 开始生效时间戳
    iat(Issued at) 签发时间
    jti(JWT ID): 唯一标识
    公共的声明: 一般添加业务相关的必要信息,因为可解密,不建议敏感信息。
    私有的声明:提供者和消费者共同定义的声明,Base64对称解密,不建议敏感信息
    Signature签证
    签证信息包括三部分:
    Base64加密的header
    Base64加密的payload
    secret-密钥
    使用header中声明的加密算法对Header和payload的加密连接字符串进行加盐secret组合加密。
    密钥保存在服务端,服务端根据密钥进行解密验证。

java-jwt 的使用

(1) java-jwt是Java语言中推荐的JWT实现库,使用Maven导入如下:

1
2
3
4
5
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.3</version>
</dependency>

(2) 生成 token:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
    * 生成 token
    * */

    public static String signToken(String app_key ,String app_secret){
        try {
            //过期时间
            Date date = new Date(System.currentTimeMillis()+EXPIER_TIME);
//            私钥加密
            Algorithm algorithm = Algorithm.HMAC256(app_secret);
            Map<String,Object> header = new HashMap<String, Object>(2);
            header.put("typ","JWT");
            header.put("alg","HS256");
            String token = JWT.create()
                    .withHeader(header)
                    .withClaim("appId",app_key)
                    .withExpiresAt(date)
                    .sign(algorithm);

            return token;
        }catch (Exception e){
            return null;
        }
    }

(3) 检验token是否正确:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
    * 检验token是否正确
    * */

    public static boolean verifyToken(String token,String app_id,String app_secret){
        try{
            Algorithm algorithm = Algorithm.HMAC256(app_secret);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            String appid = jwt.getClaim("appId").asString();
            if (app_id.equals(appid)){
                return true;
            }else {
                return false;
            }
        }catch (Exception e){
            return false;
        }
    }