JWT【详解】

目录

JWT简介

JWT的应用

        1.授权

        2.信息交换

JWT与session的差异

        session存在的问题:

        JWT:

        JWT的优势

        JWT认证流程

        JWT组成

        JWT的环境搭建

        JWT的解码

        JWT的发送和接收


JWT简介

        JWT全称叫json web token. 通过数字签名的方式,以json对象为载体,在不同的服务器终端之间安全的传输信息。

        JWT在前后端分离系统,或跨平台系统中,通过JSON形式作为WEB应用中的令牌(token),用于在各方之间安全地将信息作为JSON对象传输。在数据传输过程中,还可以完成数据加密、签名等相关处理。

        前端应用在访问后端应用时,会携带令牌(token),后端应用在接到令牌(token)后,会验证令牌(token)的合法性。从而决定前端应用是否能继续访问。

        JWT还可以系统之间进行信息传递,A系统通过令牌对B系统进行数据传输,在传输过程中,可以完成数据的加密,B系统拿到数据后,通过签名进行验证,从而判断信息是否有篡改。

JWT的应用

        JWT最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含JWT,系统在每次处理用户请求之前,都要先进行JWT安全校验,通过之后再进行处理。

        1.授权

        这是JWT最常见方案,一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。

        2.信息交换

        JWT是在各方之间安全地传输信息的好方法,可以验证传输内容是否遭到篡改。

JWT与session的差异

        session存在的问题:

        1、每个用户经过我们的应用认证之后,将认证信息保存在session中,由于session服务器中对象,随着认证用户的增多,服务器内存开销会明显增大。

        2、用户认证之后,服务端使用session保存认证信息,那么要取到认证信息,只能访问同一台服务器,才能拿到授权的资源。这样在分布式应用上,就需要实现session共享机制,不方便集群应用。

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

        JWT:

        JWT认证基于令牌,该令牌存储在客户端。但认证由服务器端进行,解决服务器内存占用问题。当用户提交用户名和密码时,在服务器端认证通过后,会生成token令牌。然后将令牌响应给客户端浏览器。

        客户端浏览器会在本地存储令牌。在客户端再次请求服务器接口时,每次都会携带JWT,在服务器验证通过后,再继续访问服务器资源。

        JWT的优势

        1、简洁,可以通过URL、POST参数或Http  header发送,因为数据量小,传输速度快。

        2、自包含,负载(属于JWT的一部分)中包含了用户所需要的信息,不需要在服务器端保存会话信息,不占服务器内存,也避免了多次查询数据库,特别适用于分布式微服务。

        3、因为token是以json加密的形式保存在客户端的,所以JWT可以跨语言使用,原则上任何WEB形式都支持。

        JWT认证流程

        1、前端将用户名和密码发送到后端服务器。后端服务器对用户名和密码验证通过后,将用户信息作为JWT Payload负载,将其与头部进行Base64编号拼接后签名,形成JWT。形成的JWT本质上就是一个形如lll.zzz.xxx的字符串。

        2、后端将JWT字符串作为登陆成功的返回结果返回给客户端。前端可以将返回结果保存在localStorage,退出登陆时,前端删除保存的JWT即可。

        3、前端在每次请求时将JWT放入HTTP  Header中的Authorization位。

        4、后端检查是否存在,如果验证JWT有效,后端就可以使用JWT中包含的用户信息。

        JWT组成

        JWT其实就是一段字符串,由标头有效负载签名这三部分组成,用  .  拼接

Header{ //标头
   ‘typ’:’JWT’,    表示token类型
   ‘alg’:’HS256’   表示签名算法
}
Payload //有效负载
{
   ‘userCode’:’43435’,
  ‘name’:’john’,
  ‘phone’:'13950497865'
}

        Signature签名

        前面两部分都使用Base64进行编码,前端可以解开知道里面的信息, Signature需要使用编码后的header和payload以及我们提供的一密钥,然后使用header中指定的签名算法进行签名,以保证JWT没有被篡改过。

        使用Signature签名可以防止内容被篡改。如果有人对头部及负载内容解码后进行修改,再进行编码,最后加上之前签名组成新的JWT。那么服务器会判断出新的头部和负载形成的签名和JWT附带的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。

        JWT的环境搭建

        在pom.xml文件中导入依赖:

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.13.0</version>
</dependency>

        创建signature       

private static String signature = "Yuu";
    public String createToken(Map<String,String> map){
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MINUTE,30);
 	//header标头可不写,默认为JWT
        JWTCreator.Builder builder = JWT.create();
        for(String key : map.keySet()){
 	    //payload负载,具体数据
            builder.withClaim(key,map.get(key));
        }
        String token = builder.withExpiresAt(c.getTime())
                .sign(Algorithm.HMAC256(signature));
        return token;
    }

        JWT的解码

public String verify(String token,String key){
        //创建解码对象
        JWTVerifier jwtVerifier =  JWT.require(
                Algorithm.HMAC256(signature)).build();
        DecodedJWT dj =  jwtVerifier.verify(token);
        String value = dj.getClaim(key).asString();

        return value;
    }

        JWT的发送和接收

        在应用控制器Controller中,通过响应头发送给客户端。

response.setHeader("token", JWT字符串);

        客户端通过axios接收响应头,并保存在sessionStorage中。

var param = {name:"tom",pwd:"111"};
await axios.get("/user/login",{params:param}).then(e => {
         var info = e.data;//响应消息体
         sessionStorage.setItem("token",e.headers.token);
});

        客户端再次请求,读取localStorage的JWT信息,以请求头的方式,发送给服务器。

var tk = localStorage.getItem("token");

axios.get("/user/getLoginUser",
   {headers:{token:tk}}).then(e => {
                                 info = e.data;
                            });

        服务器从请求头中得到jwt字符串,解析后,得到数据。

String value = new JWTUtil().verify(
        req.getHeader("token"),"userName")

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值