JWT详解与基本使用(保姆教程)

前言: 最近准备写一篇关于security前后端分离场景下的认证与授权文章,里面使用到了jwt,所以就写了一篇jwt的文章,作为开头小菜😋

概述

讲jwt之前,先讲一下什么是token?

token其实就是服务端在用户认证成功(登陆成功)之后生成的一串加密字符串,用户每次发送请求 请求后端资源时也发送给服务端,从而 验证用户身份的合法地位(即你是谁,有没有资格访问),允许用户访问该令牌允许的路由、服务和资源等,所以说token的主要作用就是用户授权,如下图

JWT详解与基本使用(保姆教程)

什么是jwt?

jwt就是JSON Web Token,他是一种使用密钥(使用 HMAC 算法)或使用 RSAECDSA 的公钥/私钥对进行加密的token,也是目前最常用的一种token

构成

jwt由三部分组成,分别是 header(头部)、 payload(有效载荷)、 signature(签名)组成,用 . 进行连接,所以token(代指JWT)通常的格式是 : aaa.bbb.ccc

头部通常由两部分组成:令牌的类型(即 JWT)和正在使用的签名算法(如 HMAC SHA256 或 RSA),例如:

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

然后此 JSON 被 Base64Url 编码形成 JWT 的第一部分

另外,常用的签名算法还有:

HS256 HS384 HS512 PS256 PS384 PS512 RS256 RS384 RS512 ES256 ES256K 等,大家根据自己习惯选择签名算法(这个影响不大)

算法原理啥的就不说了,大家有兴趣自己去百度😊

Payload

payload谷歌翻译为有效载荷,但我觉得其实就是内容的意思,我们可以把想要存的一些信息以json字符串的形式存储在这里。比如用户id等用户信息。同时还可以存放 iss(颁发者), exp(到期时间)等声明(详情可以查看官方文档)。例如:

{
   "id":1,
   "username" : "mango",
   "exp":"1664812343"
}

然后此json也会被 Base64Url 编码形成 JWT 的第二部分

Signature

签名用于验证 token在此过程中未被更改,并且对于使用私钥签名的令牌,它还可以验证 JWT 的发送者是否是它所说的人。

通过编码后的 header、编码后的 payload然后使用 header中声明的加密算法进行加盐 secret组合加密得到一个字符串,这就是token的 第三部分

例如,如果要使用 HMAC SHA256 算法,将按以下方式创建签名:

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

注意: secret是保存在服务端并进行签发的,secret就是用来进行jwt的签发与验证,就是相当于一个密钥,一旦泄露给客户端,意味着客户端也能自我签发jwt

总结

所以jwt除了用于token鉴权以外,还可以进行信息的安全传输,因为通过签名可以确定用户(使用私钥)和防止内容被篡改。(当然缺点就是传输的信息是公开的)

注意:因为 token用来加密的算法仅仅是用于 加密签名,防止 token被篡改,而存储用户信息的 payload仅仅是用 Base64Url编码而成,其他人可以 通过解码获取信息,所以不建议把用户 敏感信息(如用户密码)存入 token(防止泄漏)😱

token的基本使用

项目依赖,这里使用的是auth0,可以去 官网 根据自己算法需要选择依赖

<dependency>
    <groupid>com.auth0</groupid>
    <artifactid>java-jwt</artifactid>
    <version>3.18.2</version>
</dependency>

生成token😊

public class Main {
    public static void main(String[] args) {
        //&#x65F6;&#x95F4;&#x5DE5;&#x5177;&#x7C7B;
        Calendar instance = Calendar.getInstance();
        //&#x8BBE;&#x7F6E;&#x8FC7;&#x671F;&#x65F6;&#x95F4;  &#x5355;&#x4F4D;&#xFF1A;SECOND&#x79D2;  &#x4E00;&#x4E2A;&#x5C0F;&#x65F6;&#x5931;&#x6548;
        instance.add(Calendar.SECOND,60*60);

        JWTCreator.Builder builder = JWT.create()
                //&#x6DFB;&#x52A0;&#x952E;&#x503C;&#x5BF9;&#x6570;&#x636E;
                .withClaim("id", 1)
                //&#x6DFB;&#x52A0;&#x8FC7;&#x671F;&#x65F6;&#x95F4; exp &#x4E5F;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;key&#x4E3A;exp valus&#x4E3A;&#x5230;&#x671F;&#x65F6;&#x95F4;&#x7684;&#x65F6;&#x95F4;&#x6233;&#x548C;&#x8FD9;&#x4E2A;&#x6548;&#x679C;&#x4E00;&#x6837;
                //.withClaim("exp",1664815770)
                .withExpiresAt(instance.getTime());
        // &#x9009;&#x62E9;&#x7B7E;&#x540D;&#x7B97;&#x6CD5;HMAC256 &#x6DFB;&#x52A0;&#x5BC6;&#x94A5;&#x5B57;&#x7B26;&#x4E32;mango&#xFF08;&#x76D0;&#xFF09;
        String token = builder.sign(Algorithm.HMAC256("mango"));
        //&#x8F93;&#x51FA;token
        System.out.println(token);

    }
}

验证token并获取数据😱

public class Main {
    public static void main(String[] args) {
        //&#x9A8C;&#x8BC1;&#x7684;token
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY0ODIwMDUzfQ.SNy4Venx_AE8eqow6c3bVNwbmlX7-iz8OiDiPntY6DA";
        try{
            //&#x63D0;&#x4F9B;&#x5BC6;&#x94A5;&#x5B57;&#x7B26;&#x4E32;&#xFF08;&#x76D0;&#xFF09;&#x548C;token
            DecodedJWT jwt = JWT.require(Algorithm.HMAC256("mango")).build().verify(token);
            //&#x8F93;&#x51FA;&#x5B58;&#x50A8;&#x5728;Payload&#x4E2D;&#x952E;&#x503C;&#x5BF9;key&#x4E3A;id&#x7684;value &#x5373;id
            System.out.println(jwt.getClaim("id"));
            //token&#x8BBE;&#x7F6E;&#x8FC7;&#x671F;&#x65F6;&#x95F4;&#x5C31;&#x4F1A;&#x6709;key&#x4E3A;exp&#x7684;&#x952E;&#x503C;&#x5BF9; value&#x662F;&#x5230;&#x671F;&#x65F6;&#x95F4;&#x7684;&#x65F6;&#x95F4;&#x6233;
            System.out.println(jwt.getClaim("exp"));
        }catch (TokenExpiredException e){
             //&#x4EE4;&#x724C;&#x8FC7;&#x671F;&#x629B;&#x51FA;&#x5F02;&#x5E38;
            System.out.println("&#x4EE4;&#x724C;&#x8FC7;&#x671F;");
        }catch (Exception e){
            //token&#x975E;&#x6CD5;&#x9A8C;&#x8BC1;&#x5931;&#x8D25;&#x629B;&#x51FA;&#x5F02;&#x5E38;
            System.out.println("&#x68C0;&#x9A8C;&#x5931;&#x8D25;");
        }
    }
}

这就是token最基本的生成与验证使用,实际使用中一般是集成一个工具类使用。

结语:因为打算写一篇关于security前后端分离场景下的认证与授权文章,其中就是使用security+jwt实现的认证授权,所以就先写一篇有关于jwt的文章,大家要是觉得有用的话点个赞吧😘,下篇见😊

Original: https://www.cnblogs.com/hyjmango/p/16753100.html
Author: 芒果mango404
Title: JWT详解与基本使用(保姆教程)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/616061/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球