KS-JWT学习

本文介绍了JWT(Json Web Token)在身份验证中的应用,对比了session和cookie的局限,并详细解析了JWT的构成,包括头部、负载和签证,以及如何使用Java实现JWT的创建和验证。着重讨论了JWT在解决分布式系统扩展问题上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.JWT

Json web token (JWT),主要用于做身份鉴别或者资源接口的安全机制。

2.基于session认证显露的问题

1.session通常都是保存在内存中的,随着认证用户的增多,服务器的资源消耗会增大。
2.用户认证的信息保存在内存中,这就意味着用户下次请求还必须请求这台服务器,才能拿到授权的资源,
这样在分布式系统限制了应用的扩展能力。
3.cookie如果被截获,用户容易受到跨站请求伪造攻击。

3.JWT的构成

第一部分:头部(header)
第二部分:负载(payload)
第三部分:签证(signature)
header

JWT的头部承载两部分信息:
 
{
  'typ':'JWT', //声明类型
  'alg':'HS256' //声明加密的算法
}

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分。
playload

载荷就是存放有效信息的地方。

1.标准中注册的声明。
2.公共的声明
3.私有的声明

标准中注册的声明(建议但不强制使用):
1.iss:JWT签发者
2.sub:JWT所面向的用户
3.aud:接收JWT的一方
4.exp:JWT的过期时间,这个过期时间必须要大于签发时间
5.nbf:定义在什么时间之前,该JWT都是不可用的
6.iat:JWT的签发时间
7.jti:JWT的唯一身份标识

公共的声明

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务信息,但不建议添加敏感信息,因为
该部分在客户端可以解密。

私有的声明
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着
该部分信息可以归类为明文信息。

定义一个payload:
{
   "sub":"xxxxx",
   "name":"John Doe",
   "admin":"xx"

}
然后进行base64加密,得到JWT的第二部分。
signature
JWT的第三部分是一个签证信息,这个签证信息由三部分组成:

1.header(base64加密后)
2.payload(base64加密后)
3.secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header
中声明的加密方式进行加盐secret组合加密,然后就构成了JWT的第三部分。
 
a1 =  base64UrlEncode(header)+"."+base64UrlEncode(payload);

signature = HMACSHA256(a1,'secret');

base64UrlEncode(header).base64UrlEncode(payload).signature 

4.JWT实战

1.导入pom

<dependency>
	<groupId>com.auth0</groupId>
	<artifactId>java-jwt</artifactId>
	<version>3.18.1</version> 
</dependency>
2.JwtService


package com.ldd.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * @author 小李同学
 * @pageage com.ldd.utils
 * @date
 * @week
 * @action
 */
@Slf4j
public class JwtService {


    //定义加密的盐信息
    private static final String KEY = "siZong";
    //签发者
    private static final String ISSUSER = "YYKK";
    //token过期时间
    private static final Long TOKEN_EXPIRE_TIME = 1000 * 60L;

    /**
     * @Author: 13513
     * @Date: 2021/9/5 13:05
     * @Param:
     * @Return: 创建jwt 可以指定如下参数
     * JWT.create().withIssuer("签发人")
     * .withExpiresAt(new Date())...//到期时间 超过到期时间会抛出TokenExpiredException
     * iss (issuer):签发人
     * exp (expiration time):过期时间
     * sub (subject):主题
     * aud (audience):受众
     * nbf (Not Before):生效时间
     * iat (Issued At):签发时间
     * jti (JWT ID):编号
     * 注意:不设置过期时间就是永久token
     */
    public String createToken() {
        Date now = new Date();
        //1.定义算法
        Algorithm algorithm = Algorithm.HMAC256(KEY);
        //2.开始创建和生成token
        String token = JWT.create()
                .withIssuer(ISSUSER) //签发者
                .withIssuedAt(now) //签发时间
                .withExpiresAt(new Date(now.getTime() + TOKEN_EXPIRE_TIME))
                .withClaim("userName", "userName")
                .withClaim("openId", "openId")
                .sign(algorithm);
        return token;
    }

    public String verifyToken(String token) {
        //1.定义算法
        Algorithm algorithm = Algorithm.HMAC256(KEY);
        //2.进行校验
        JWTVerifier verifier = JWT.require(algorithm)
                .withIssuer(ISSUSER)
                .withClaim("userName", "userName")
                .build();
        //3.如果校验成功,可以从jwt获取定义的内容
        //  如果校验失败,则抛出异常
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaim("openId").asString();
    }


    public static void main(String[] args) {
        JwtService jwtService = new JwtService();
        String token = jwtService.createToken();
        log.info("token:" + token);
        String openId = jwtService.verifyToken(token);
        log.info("openId:" + openId);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值