JWT for Java: 详细解析与实践

一、什么是JWT

JSON Web Token(JWT)是一种用于安全传输信息的开放标准,基于 JSON 格式定义了一种紧凑且自包含的方式来在各方之间安全地传输信息。JWT 可以被用作验证身份、信息交换的 token。

一个 JWT 由三个部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature):

{
  "alg": "HS256",
  "typ": "JWT"
}
.
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
.
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

其中,头部和载荷都是 JSON 格式,签名是根据特定算法生成的字符串,用于验证 JWT 的可靠性。JWT 的优势在于它既可以存放认证信息,又可以存放其他的业务信息,而且用户信息都加密存储,不需要每次都从数据库中读取用户信息。

二、JWT的使用场景

下面列举了一些 JWT 的常见使用场景:

  • 用户身份验证:用户登录后服务器返回 JWT,客户端之后访问其他接口时携带 JWT 作为鉴权凭证。
  • 应用程序授权:JWT 用于应用程序内部接口的鉴权授权,例如微服务内部的接口访问。
  • 密码重置/邮箱验证等场景:发送 JWT 至用户邮箱或者手机,使用 JWT 验证用户身份并执行相应的操作。

三、实现JWT in Java

首先,我们需要添加相关依赖:

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

接下来,我们可以创建一个 JWTUtil 来处理操作 JWT:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;

public class JWTUtil {

  /**
   * 根据用户信息生成 jwt
   */
  public static String generateToken(User user) {
    Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);

    JwtBuilder builder = Jwts.builder()
        .setId(user.getId())
        .setIssuedAt(now)
        .setSubject(user.getName())
        .setIssuer(user.getName())
        .signWith(key);

    long ttlMillis = 86400000L; //过期时间为1天
    if (ttlMillis >= 0) {
      long expMillis = nowMillis + ttlMillis;
      Date exp = new Date(expMillis);
      builder.setExpiration(exp);
    }

    return builder.compact();
  }

  /**
   * 根据 jwt 解析用户信息
   */
  public static User parseToken(String token) {
    Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    Claims claims = Jwts.parser()
        .setSigningKey(key)
        .parseClaimsJws(token)
        .getBody();

    User user = new User();
    user.setId(claims.getId());
    user.setName(claims.getSubject());

    return user;
  }
}

四、使用 JWT 进行授权认证

在使用 JWT 进行授权认证时,通常需要将 JWT 存储在客户端(如浏览器)中,这样可以在下次访问时带上 JWT,从而进行认证。下面是一个使用 JWT 进行授权认证的示例:

@GetMapping("/users/me")
public ResponseEntity currentUser(@RequestHeader(value="Authorization") String token) {
    // 从请求头中获取 JWT
    if (token.startsWith("Bearer ")) {
        token = token.substring(7);
    }

    // 验证 JWT 并获取用户信息
    User user = JWTUtil.parseToken(token);
    if (user != null) {
        return ResponseEntity.ok(user);
    }

    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

结语

JWT 是一种非常实用的鉴权方式,它具有跨语言、解耦合等优点。在 Java 中,我们可以使用 jjwt 库来操作 JWT,可以将其用于接口鉴权、用户身份认证等场景。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/227756.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-09 16:31
下一篇 2024-12-09 16:31

相关推荐

  • Java JsonPath 效率优化指南

    本篇文章将深入探讨Java JsonPath的效率问题,并提供一些优化方案。 一、JsonPath 简介 JsonPath是一个可用于从JSON数据中获取信息的库。它提供了一种DS…

    编程 2025-04-29
  • java client.getacsresponse 编译报错解决方法

    java client.getacsresponse 编译报错是Java编程过程中常见的错误,常见的原因是代码的语法错误、类库依赖问题和编译环境的配置问题。下面将从多个方面进行分析…

    编程 2025-04-29
  • Python for循环求1到100的积

    Python中的for循环可以方便地遍历列表、元组、字典等数据类型。本文将以Python for循环求1到100的积为中心,从多个方面进行详细阐述。 一、for循环语法 Pytho…

    编程 2025-04-29
  • Java腾讯云音视频对接

    本文旨在从多个方面详细阐述Java腾讯云音视频对接,提供完整的代码示例。 一、腾讯云音视频介绍 腾讯云音视频服务(Cloud Tencent Real-Time Communica…

    编程 2025-04-29
  • Java Bean加载过程

    Java Bean加载过程涉及到类加载器、反射机制和Java虚拟机的执行过程。在本文中,将从这三个方面详细阐述Java Bean加载的过程。 一、类加载器 类加载器是Java虚拟机…

    编程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介绍

    本文将详细介绍Java Milvus SearchParam withoutFields的相关知识和用法。 一、什么是Java Milvus SearchParam without…

    编程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java语言中的一个版本,于2014年3月18日发布。本文将从多个方面对Java 8中某一周的周一进行详细的阐述。 一、数组处理 Java 8新特性之一是Stream…

    编程 2025-04-29
  • Java判断字符串是否存在多个

    本文将从以下几个方面详细阐述如何使用Java判断一个字符串中是否存在多个指定字符: 一、字符串遍历 字符串是Java编程中非常重要的一种数据类型。要判断字符串中是否存在多个指定字符…

    编程 2025-04-29
  • VSCode为什么无法运行Java

    解答:VSCode无法运行Java是因为默认情况下,VSCode并没有集成Java运行环境,需要手动添加Java运行环境或安装相关插件才能实现Java代码的编写、调试和运行。 一、…

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29

发表回复

登录后才能评论