JWT基础

什么是Token?

什么是token/token如何使用_萧先生.的博客-CSDN博客_token用法

什么是JWT?

        JSON Web Token,通过JSON形式作为web应用的令牌,用于在各方之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。

使用场景:

        第一种:授权(常用)

        前端系统访问后端系统的时候,使用功能jwt传一个令牌,如果这个令牌是后端系统可以放行的令牌,就允许访问。如果不是可以放行的令牌,或者没有携带令牌,就不允许访问

JWT基础_第1张图片

         第二种:信息交换

JWT基础_第2张图片

为什么使用JWT授权?

        1、基于传统的Session认证

        1)认证流程:

JWT基础_第3张图片

        2)缺点:

                ①每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言,session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大

                ②用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应地限制了负载均衡的能力。这也意味着限制了应用的扩展能力。

                ③因为是基于cookie来进行用户识别的,cookie如果被截获,用户就会很容易受到跨站请求伪造的危机。

                ④在前后端分离的系统中,前端系统在调用后端系统的时候,中间可能会经过很多的代理,那么每一层都要携带sessionId,如果后端是集群部署,还要实现session共享。

        2、基于JWT认证

        1)JWT的认证流程

JWT基础_第4张图片

        认证通过之后,会通过JWT生成一个令牌,这个令牌永久保存在本地(浏览器端),以后前端每次访问后端的时候,后端只需要对携带的JWT进行一个认证,如果令牌合法,就可以调用,如果不是合法令牌,就直接返回错误信息。

        2)优势:

                ①简洁:可以通过url或者post参数或者在http header中发送,数据量小,传输速度快

                ②自包含:可以直接从payload中取出用户信息,不需要查询数据库

                ③因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持

                ④不需要在服务端中保存会话信息,特别适用于分布式微服务

JWT结构:

        JWT组成:Header.Payload.Signature

        1、标头(Header)   

标头组成:①令牌类型(typ)        ②签名算法

会使用Base64编码Header

注意:

Base64是一种编码,也就是说,它是可以被翻译回原来的样子的,它并不是一种加密过程

{
    "alg":"HS256",
    "typ":"JWT"
}

         2、有效载荷(Payload) 

      有效负载,其中包含声明,也会使用Base64编码Payload。声明是有关实体(通常是用户)和其他数据的声明。

        注意:不要在Payload里面放用户的敏感信息,比如密码。因为JWT可能被拦截,然后用Base64解码。

{
    "sub":"1234567890",
    "name":"zhangsan",
    "admin":true
}

        3、签名(Signature)

Signature需要使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法(HS256)进行签名。前面的作用是保证JWT没有被篡改过

如:

HMACSHA256(base64UrlEncode(header) +  "." + base64UrlEncode(payload).secret);

签名目的:防止内容被篡改。

JWT基础_第5张图片

使用JWT:

        1、导入依赖

        
            com.auth0
            java-jwt
            3.19.2
        

        2、生成token

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Calendar;
import java.util.HashMap;
public class Test {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,1000);
        String token = JWT.create()
                                    .withHeader(map)    //Header(可以不用设置,因为Header有默认值:{"alg":"HS256", "typ":"JWT" })
                                    .withClaim("userId",2)  //payload
                                    .withClaim("username","张三") //payload
                                    .withExpiresAt(instance.getTime())  //指定令牌过期时间
                                    .sign(Algorithm.HMAC256("MiYao"));  //Signature
        System.out.println(token);
    }
}

        输出结果:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NjEzMjQ1NjEsInVzZXJJZCI6MiwidXNlcm5hbWUiOiLlvKDkuIkifQ.m04WmTQTwVJpaRODMX8r-NxvwF_kJVP3mXo7ubX26Po

        3、根据令牌和签名解析数据

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

public class Test2 {
    public static void main(String[] args) {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NjEzMjQ1NjEsInVzZXJJZCI6MiwidXNlcm5hbWUiOiLlvKDkuIkifQ.m04WmTQTwVJpaRODMX8r-NxvwF_kJVP3mXo7ubX26Po";
        //创建验证对象
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("MiYao")).build();
        DecodedJWT verify = jwtVerifier.verify(token);
        System.out.println(verify.getClaim("userId"));
        System.out.println(verify.getClaim("username"));
        System.out.println(verify.getExpiresAt());  //过期时间
    }
}

        输出结果:

2
"张三"
Wed Aug 24 15:02:41 CST 2022

        4、常见异常信息

SignatureVerificationException        签名不一致异常
TokenExpiredException                 令牌过期异常
AlgorithmMismatchException            算法不匹配异常
InvalidClaimException                 失效的payload异常

你可能感兴趣的:(前端,json,java)