JWT初体验

JWT

JSON Web Token

https://jwt.io/

应用场景

JWT是一种基于JSON的令牌安全验证(在某些特定的场合可以替代Session或者Cookie),一次生成随处校验

JWT组成

头部信息(header)

作用:指定该JWT使用的签名

  {
      “alg”:HS256// 签名算法 默认为HS256
  }

将上面的json,用Base64URL 算法转成字符串,即为header。json

消息体playload

也就是负载的信息

{
"exp" (expiration time):过期时间
"sub" (subject):主题,一般用用户id,用来标识用户会话
"iat" (Issued At):签发时间
}

这个 JSON 对象也要使用 Base64URL 算法转成字符串。
作用:JWT的请求数据

签名( signature)

Signature 部分是对前两部分的签名,防止数据篡改。
需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

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

头部、声明、签名用 . 号

最终:把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔连在一起就得到了我们要的JWT

实现

依赖

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!--JWT-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.7.0</version>
    </dependency>
</dependencies>

JwtUtil

public class JwtUtil {
    /**
     * 密钥,仅服务端存储
     */
    private static String secret = "ko346134h_we]rg3in_yip1!";

    /**
     *
     * @param subject 消息体
     * @param issueDate 签发时间
     * @return
     */
    public static String createToken(String subject, Date issueDate) {

        Calendar c = Calendar.getInstance();
        c.setTime(issueDate);
        c.add(Calendar.DAY_OF_MONTH, 20);

        String compactJws = Jwts.builder()
                .setSubject(subject)
                .setIssuedAt(issueDate)
                .setExpiration(c.getTime())
            	//签名算法 默认为HS256
                .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, secret)
                .compact();
        return compactJws;
    }

    /**
     * 解密 jwt
     * @param token
     * @return 消息体
     * @throws Exception
     */
    public static String parseToken(String token) {
        try {
            Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
            if (claims != null){
                return claims.getSubject();
            }
        }catch (ExpiredJwtException e){
            e.printStackTrace();
            System.out.println("jwt过期了");
        }

        return "";
    }
}
Filter校验
@WebFilter(urlPatterns = "/**")
@Component
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        String token = req.getHeader("token");

        if (StringUtils.isEmpty(token)) {
            System.err.println("没有登陆");
        } else {
            //自动续期  手动续期
            String parseToken = JwtUtil.parseToken(token);
            if (StringUtils.isEmpty(parseToken)) {
                System.out.println("请进");
                chain.doFilter(request, response);
            }
        }

    }
}

测试

public class JwtTest {
    public static void main(String[] args) {
        String token = JwtUtil.createToken("userId=1,role=admin", new Date());
        System.out.println("token:" + token);
        String[] split = token.split("\\.");
        System.out.println("头部信息:" + new String(Base64.getDecoder().decode(split[0])));
        System.out.println("消息体:" + new String(Base64.getDecoder().decode(split[1])));

        String s = parseToken(token);
        System.out.println("解码后信息:" + s);

        try {
            parseToken(token+"1");
        }catch (JwtException e){
            //错误token
            e.printStackTrace();
        }
    }
}

输出

token:eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VySWQ9MSxyb2xlPWFkbWluIiwiaWF0IjoxNjIzMjI1MTc5LCJleHAiOjE2MjQ5NTMxNzl9.NFSWs4GovUDOIrrY9-66DmSiR7jLzP65vpwGR1biMuSX4WsGBlPMG7Vj-YZZOcKMggzmb0yl5e77fchEU5QGQA
头部信息:{"alg":"HS512"}
消息体:{"sub":"userId=1,role=admin","iat":1623225179,"exp":1624953179}
解码后信息:userId=1,role=admin
io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:354)
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
	at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541)
	at com.example.jwt.JwtUtil.parseToken(JwtUtil.java:56)
	at com.example.jwt.JwtTest.main(JwtTest.java:27)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值