JWT基础概念

1. 介绍

JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。 从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。

JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。

2.JWT的组成

1.标头(Header)
2.有效载荷(Payload)
3.签名(Signature)

Header部分:

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

该字段为Json格式,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256),
typ属性表示令牌的类型,JWT令牌统一写为JWT(默认也为JWT)。
JSON 形式的 Header 被转换成 Base64 编码,成为 JWT 的第一部分。

Payload部分:
Payload 也是 JSON 格式数据,其中包含了 Claims(声明,包含 JWT 的相关信息)。

Claims 分为三种类型:

Registered Claims(注册声明) :预定义的一些声明,建议使用,但不是强制性的,可互操作的声明。
Public Claims(公有声明) :JWT 签发方可以自定义的声明,但是为了避免冲突,应该在 IANA JSON Web Token Registry 中定义它们。
Private Claims(私有声明) :JWT 签发方因为项目需要而自定义的声明,更符合实际项目场景使用。
下面是一些常见的注册声明:

iss(issuer):JWT 签发方。
iat(issued at time):JWT 签发时间。
sub(subject):JWT 主题。
aud(audience):JWT 接收方。
exp(expiration time):JWT 的过期时间。
nbf(not before time):JWT 生效时间,早于该定义的时间的 JWT 不能被接受处理。
jti(JWT ID):JWT 唯一标识。

{
  "uid": "ff1212f5-d8d1-4496-bf41-d2dda73de19a",
  "sub": "1234567890",
  "name": "John Doe",
  "exp": 15323232,
  "iat": 1516239022,
  "scope": ["admin", "user"]
}

Payload 部分默认是不加密的,一定不要将隐私信息存放在 Payload 当中!!!

JSON 形式的 Payload 被转换成 Base64 编码,成为 JWT 的第二部分。

Signature部分
Signature 部分是对前两部分的签名,作用是防止 JWT(主要是 payload) 被篡改。
这个签名的生成需要用到:

  • Header(加密)+ Payload(加密)。
  • 存放在服务端的密钥(不能泄露)。
  • 签名算法。
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,这个字符串就是 JWT 。

3.生成,解析Token代码


    private static  long time = 1000*60*60*24;
    private static String  signature = "admin";  //加密 ,解密需要

    /**
     * setHeaderParam -> 设置 Header头信息
     * claim -> 携带的数据
     * setSubject -> 设置主机
     * setExpiration -> 保存时间
     * setId -> 设置ID
     * signWith -> 声明算法和签名
     * compact -> 拼接
     */
    @Test
    void contextLoads() {
        JwtBuilder builder = Jwts.builder();
        final String token = builder   
                 //header
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                //保存用户名,以及角色,注意这里最好保存非私密信息,比如密码最好不要保存
                .claim("username", "admin")
                .claim("role", "admin")
                .setSubject("admin-test")
                //设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + time))
                .setId(UUID.randomUUID().toString())
                // 设置算法及密钥  java通过signature生成签名,解密也需要signature
                .signWith(SignatureAlgorithm.HS256, signature) 
                .compact();
        System.out.println(token);
    }


       @Test
    void parse() {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" +
                ".eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwic3ViIjoiYWRtaW4tdGVzdCIsImV4cCI6MTY" +
                "2NjYxNTM5NSwianRpIjoiOGMyZTRiZGEtYTI5Mi00NzE3LThlZjYtYjExNTI0N2ZkMzljIn0" +
                ".XLF9HPezm4w6b8LIloQz_pDemshAp0ublOfbmft2nbA";
        JwtParser jwtParser = Jwts.parser();
        //通过该签名对token进行解析,解析成为多个claim
        Jws<Claims> claimsJws = jwtParser.setSigningKey(signature_key).parseClaimsJws(token);
        System.out.println(claimsJws.toString());
        Claims claims = claimsJws.getBody();
        System.out.println("用户名 "+claims.get("username"));
        System.out.println("角色信息 "+claims.get("role"));
    }
    }

在这里插入图片描述

4.token在用户登录时的应用

token都是在用户登录时生成,并且进行判断,进行更新,下图简略的概要token生成,以及更新。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值