JWT初识记录

由于前一段时间作了一个系统持续操做期间自动刷新token有效性的需求,而后就想着找一个空闲时间总结一下JWT,因此今天就简单的记录一下本身了解的内容。前端


JWT是什么

  1. JWT全称是JSON Web Token,是一个开放标准,它定义了一种紧凑的、自包含的结构,可用于在服务之间信息传递和受权认证。
  • 信息传递:经过签名,能够确保传递的信息不被篡改且不是伪造的。
  • 受权认证:经过JWT生成的token信息进行验签,确保是本身服务签发的token信息。
  1. JWT的格式:

JWT由三部分组成,各部分之间使用[.]进行链接。各部分分别是:Header(头信息)、Payload(载荷)和Signature(签名)。java

其格式以下:web

header.payload.signature
  1. 使用场景

前端页面点击登陆,后端验证用户名密码经过后,使用JWT生成token信息返回给前端,前端使用登陆token请求各个接口。redis


JWT使用示例

首先引入JWT jar包以下:算法

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.6.0</version>
</dependency>

Java示例代码以下:json

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.*;

public class JWTDemo {

    public static void main(String[] args) {
        String issue = "ISSUE_CESHI";
        // 签名算法
        SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
        // 签名秘钥
        String secret = "CESHI_SECRET";
        int timeout = 60 * 60 * 6;

        long currentTime = System.currentTimeMillis();
        Map<String,Object> map = new HashMap<>();
        map.put("userId","10");
        map.put("userName","张三");

        String token = Jwts.builder()
                .signWith(algorithm, secret)
                .setClaims(map)
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))
                .setIssuer(issue)
                .setExpiration(new Date(currentTime + timeout * 1000))
                .compact();
        System.out.println(token);

        Jws<Claims> parseResult3 = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
    }
}

上面演示代码生成的token信息以下:后端

eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJJU1NVRV9DRVNISSIsInVzZXJOYW1lIjoi5byg5LiJIiwiZXhwIjoxNjEwMzgzMzY0LCJ1c2VySWQiOiIxMCIsImlhdCI6MTYxMDM2MTc2NCwianRpIjoiY2QwNDM1ODctNGZmNS00OGY4LTk2YjUtNTA1ZTc4MzFkMGNjIn0.b_Fr8hpTC5nlwR4NikbEg1WpDMya2Gr5fCfNTV0iCOQ

而后将生成的token进行解析获得以下内容:缓存

能够看到载荷里面有咱们设置的userId和userName信息。dom

同时,JWT规定了7个官方的字段,以下:ui

  • iss (issuer):签发人
  • exp (expiration time):过时时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号

须要特别注意的是,JWT的header和body部分都是用Base64进行编码的,自己不具备加密属性,因此在body中不能存储敏感信息。


系统持续操做自动刷新token

JWT的一大优势就是token信息存储在客户端,服务端不用存储对应的受权信息。所以,它的一大缺点就是一旦token颁发了就没办法进行撤销,只有等待token自动失效。

若是想要实现token失效前撤销,那么只能借助其余手段,好比使用redis缓存,token验证除了JWT自己的验签外,还须要判断redis缓存信息,可是这样作有违JWT的设计本意。

说说在项目中遇到的需求:就是在用户持续间隔时间内操做系统,那么系统内部应该自动刷新token信息,而不是在固定时间点强行要求从新登陆。好比token颁发的有效期是5个小时,而后用户一直操做到4小时59分59秒,而后在5小时0分1秒的时候提交一个表格,这时若是由于token失效直接跳转到登陆页面,这样的用户体验感是极为糟糕的。

因此为了解决上面的场景,在写这个需求的时候,特意调研了一下各类方案,最后综合了一下,决定采用redis实现。方案以下:

颁发一个足够时长的token(好比15天),而后存储在redis中,redis中设置短的有效期,好比6小时。从而实如今6小时内有效操做免登陆。

相关文章
相关标签/搜索