缘博客
发布日期

登录认证:JWT令牌

作者
  • 姓名
    社交账号

JWT是什么

JWT 全称 JSON Web Token,是一种简洁、自包含的令牌格式。

在登录认证中:

登录成功
生成JWT
返回给浏览器
后续请求携带JWT
服务器解析并校验JWT

JWT的组成

JWT 由三部分组成:

Header.Payload.Signature

记录令牌类型、签名算法等信息,例如:

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

Payload

保存需要携带的业务数据,例如:

{
  "id": 1,
  "username": "Tom"
}

Signature

签名用于防止 Token 被篡改。它会综合 Header、Payload、密钥和签名算法计算得到。

Header + Payload + Secret
       签名算法
       Signature

如果 Payload 被修改,而签名没有使用合法密钥重新计算,校验就会失败。


Base64

课程中提到 Header 和 Payload 会经过 Base64 编码形成可传输字符串。

Base64 是编码方式,不是加密方式。JWT 的完整性主要依赖 Signature 校验。


引入JWT依赖

课程示例使用:

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

通过 Jwts 工具类生成和解析 Token。


生成JWT

@Test
public void testGenJwt() {
    Map<String, Object> claims = new HashMap<>();
    claims.put("id", 10);
    claims.put("username", "itheima");

    String jwt = Jwts.builder()
            .signWith(SignatureAlgorithm.HS256, "SVRIRUlNQQ==")
            .addClaims(claims)
            .setExpiration(new Date(System.currentTimeMillis() + 12 * 3600 * 1000))
            .compact();

    System.out.println(jwt);
}

生成过程:

准备Claims
指定签名算法与密钥
设置过期时间
生成Token

claims 中的数据最终进入 Payload。


解析JWT

@Test
public void testParseJwt() throws Exception {
    String jwtToken = "...";

    Claims claims = Jwts.parser()
            .setSigningKey("SVRIRUlNQQ==")
            .parseClaimsJws(jwtToken)
            .getBody();

    System.out.println(claims);
}

解析时会完成签名和有效期校验。

课程中指出,两种常见情况会导致解析失败:

  • Token 被篡改。
  • Token 已经过期。

生成和解析时使用的签名密钥必须配套一致。


登录成功后生成Token

登录成功后的完整流程:

POST /login
根据用户名密码查询员工
查询成功
生成JWT
组装登录返回数据
返回给前端

前端拿到 Token 后保存,并在后续访问受保护接口时携带。


JWT与统一拦截

JWT 只解决“登录标记”问题,真正的登录校验还需要统一拦截:

浏览器请求
Filter / Interceptor
读取Token
解析JWT
成功 → 放行
失败 → 401

因此课程后续继续使用 Filter 和 Interceptor 实现统一认证。