详解JWT token心得与使用实例

以下是详解JWT token心得与使用实例的完整攻略。

什么是JWT

JWT(JSON Web Token)是一种开放标准,定义了用于在网络应用程序间传递声明的一个紧凑、自包含的方式。JWT 这个标准定义了一种简洁且安全的方式,可以在各方之间传输包含各种信息的 JSON 对象。JWT 主要用于身份验证和授权。

JWT 的组成结构

一个 JWT token 由三部分构成,它们之间通过"."连接,分别是:

  • Header(头部)
  • Payload(负载)
  • Signature(签名)

下面是一个 JWT token 的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

它的三个部分依次是:

Header

Header 部分通常由两部分组成:令牌的类型和使用的签名算法。Header部分通常长这个样子:

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

其中:

  • alg 表示签名算法,这里使用的是 HS256(HMAC with SHA-256)
  • typ 是令牌的类型,这里是 JWT

Payload

Payload 部分也是由两部分组成:声明和数据。

声明通常有一些预定义的属性,也允许定义自己的属性。实际应用中,建议使用预定义的属性。

常见的预定义声明有:

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

一个示例 Payload:

{
  "iss": "test",
  "exp": 1516239022,
  "name": "John Doe",
  "admin": true
}

这个 Payload 包括了四个属性:

  • iss 表示这个 JWT 的签发者是 test
  • exp 表示这个 JWT 在 1516239022 秒之后过期
  • name 和 admin 则是自定义的属性

Signature

JWT 的第三部分是 signature ,这个部分将前两部分通过一个特定的算法进行签名生成,然后添加在 JWT 的后面。如果前两部分分别是:header和 payload ,那么使用 key 进行签名的伪代码如下:

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

其中,secret 为签名的密钥。

如何使用JWT

要使用 JWT,需要了解如何生成和解析 JWT。

生成 JWT

Java 中生成 JWT,我们可以使用io.jsonwebtoken.Jwts类。以下是一个生成 JWT 的示例:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtils {

    private static final long EXPIRATION_TIME = 1000 * 60 * 60 * 24; // 一天的毫秒数
    private static final String SIGNATURE_KEY = "mykey"; // TODO: 这里需要替换成自己的密钥

    public String generateToken(String username, String role) {
        Date now = new Date();
        Date expirationDate = new Date(now.getTime() + EXPIRATION_TIME);

        return Jwts.builder()
                .setSubject(username)
                .claim("role", role)
                .setIssuedAt(now)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS256, SIGNATURE_KEY)
                .compact();
    }
}

这个示例中,我们使用 Jwts 类生成了一个 JWT。其中:

  • setSubject():表示这个 JWT 的主题,一般是用户的唯一标识符
  • claim():表示自定义的声明
  • setIssuedAt():表示这个 JWT 的签发时间
  • setExpiration():表示这个 JWT 的过期时间
  • signWith():表示使用指定的签名算法和密钥对 JWT 进行签名
  • compact():表示将 JWT 转换为字符串并返回

解析 JWT

在 Java 中解析 JWT,我们同样可以使用io.jsonwebtoken.Jwts类。以下是一个解析 JWT 的示例:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

public class JwtUtils {

    private static final String SIGNATURE_KEY = "mykey"; // TODO: 这里需要替换成自己的密钥

    public void parseToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SIGNATURE_KEY)
                .parseClaimsJws(token)
                .getBody();

        String username = claims.getSubject();
        String role = claims.get("role", String.class);

        System.out.println("username: " + username);
        System.out.println("role: " + role);
    }
}

这个示例中,我们使用 Jwts 类解析了一个 JWT。其中:

  • setSigningKey():表示使用指定的密钥对 JWT 进行解密
  • parseClaimsJws():表示将 JWT 转换为 Claims 对象
  • getSubject():表示获取 JWT 的主题
  • get():表示获取自定义的声明

使用示例

以下是两个 JWT 的使用示例。

示例 1

假设我们需要授权一个用户访问一个需要身份验证的 API。以下是一个使用 JWT 的示例:

@RestController
@RequestMapping("/api")
public class ApiController {

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        if ("admin".equalsIgnoreCase(username) && "123456".equals(password)) {
            JwtUtils jwtUtils = new JwtUtils();
            String token = jwtUtils.generateToken(username, "admin");
            return token;
        } else {
            return "Wrong username/password";
        }
    }

    @GetMapping("/hello")
    public String hello(@RequestHeader("Authorization") String authorization) {
        if (authorization != null && authorization.startsWith("Bearer ")) {
            String token = authorization.substring(7);
            JwtUtils jwtUtils = new JwtUtils();
            jwtUtils.parseToken(token);
            return "Hello!";
        } else {
            return "Unauthorized";
        }
    }
}

这个示例中,我们定义了一个需要身份验证的 API /api/hello,客户端首先需要调用 POST 接口 /api/login 来获取 JWT token。在接下来的调用 /api/hello 接口时,客户端需要在请求头中添加“Bearer ”前缀的 JWT token。服务器将从 JWT token 中获取用户信息并进行身份验证。

示例 2

假设我们需要将一些数据安全地传输给客户端。以下是一个使用 JWT 的示例:

@RestController
@RequestMapping("/api")
public class ApiController {

    private static final String SECRET_KEY = "my_secret_key"; // TODO: 这里需要替换成自己的密钥

    @GetMapping("/data")
    public Map<String, Object> getData() {
        Map<String, Object> data = new HashMap<>();
        data.put("id", 1);
        data.put("name", "John Doe");

        JwtUtils jwtUtils = new JwtUtils();
        String token = jwtUtils.generateToken(data, SECRET_KEY);

        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        return result;
    }

    @GetMapping("/data/{token}")
    public Map<String, Object> getData(@PathVariable String token) {
        JwtUtils jwtUtils = new JwtUtils();
        Map<String, Object> data = jwtUtils.parseToken(token, SECRET_KEY);
        return data;
    }
}

这个示例中,我们定义了两个接口。在第一个接口 /api/data 中,我们生成一个包含数据的 JWT,并将它作为响应返回给客户端。在第二个接口 /api/data/{token} 中,客户端将 JWT token 作为路径参数发送给服务器,服务器将从 JWT token 中解密数据并返回给客户端。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JWT token心得与使用实例 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java使用ObjectMapper的简单示例

    首先,我们需要了解一下ObjectMapper这个类,它是Jackson库中最常用的类之一,它允许Java对象与JSON对象之间的序列化和反序列化。该类提供了一系列方法,可以将Java对象转换为JSON格式,也可以将JSON格式的数据转换为Java对象。 安装Jackson依赖 如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: <de…

    Java 2023年5月26日
    00
  • Java开发中POJO和JSON互转时如何忽略隐藏字段的问题

    Java开发中POJO(Plain Old Java Object,简单Java对象)和JSON(JavaScript Object Notation,JavaScript对象表示法)的相互转换是非常常见的操作。但在转换过程中,可能会遇到一些字段需要被隐藏的情况,例如:密码字段、某些敏感信息等。这时候,就需要对转换过程进行忽略操作。 下面是一些处理Java开…

    Java 2023年5月26日
    00
  • java和Spring中观察者模式的应用详解

    我来详细讲解一下“java和Spring中观察者模式的应用详解”的完整攻略。 什么是观察者模式? 观察者模式(Observer Pattern)是一种行为型设计模式,也叫做发布-订阅模式(Publish/Subscribe),用于定义对象之间的一种一对多的依赖关系。当一个对象的状态改变时,所有依赖于它的对象都会收到通知并自动更新。观察者模式的核心思想就是解耦…

    Java 2023年5月20日
    00
  • Java Stream流的常见生成和操作方法总结

    Java Stream流的常见生成和操作方法总结 生成Stream流的常见方式 1. 通过Collection接口生成 可以通过Collection接口提供的stream()和parallelStream()方法生成一个Stream或ParallelStream流: List<String> list = Arrays.asList("…

    Java 2023年5月26日
    00
  • Java使用DateUtils对日期进行数学运算经典应用示例【附DateUtils相关包文件下载】

    我来为你详细讲解“Java使用DateUtils对日期进行数学运算经典应用示例”。 1. DateUtils是什么? DateUtils是Apache Commons Lang包中提供的一个工具类,提供了许多有用的方法来操作日期。 在Java中,使用Date类来表示日期和时间,但是其提供的接口较为简单,如想要对日期进行格式化,进行日期计算,获得某个日期的月份…

    Java 2023年5月20日
    00
  • java 浅析代码块的由来及用法

    Java 浅析代码块的由来及用法 背景介绍 在Java中,代码块是一段静态或动态语句代码,在执行时会形成一个作用域。根据代码块的位置和声明方式,可以分为实例初始化块、静态初始化块和局部代码块。 实例初始化块 实例初始化块是被定义在类内部,但没有被声明为静态的代码块,可以在创建对象时被调用,用于对对象进行初始化操作。 public class Person {…

    Java 2023年5月30日
    00
  • spring-data-redis 2.0 的使用示例代码

    Spring Data Redis是一个Spring Data项目的一部分,它提供了与Redis key-value数据库进行交互的一些功能,如分布式面向连接池的Jedis客户端、RedisTemplate、Repository等。 Spring Data Redis 2.0的使用示例代码主要分为以下几个步骤: 1. 添加依赖 在pom.xml中添加如下依赖…

    Java 2023年5月20日
    00
  • java读写二进制文件的解决方法

    JAVA是一种跨平台的编程语言,可以很好地处理二进制文件,本文将介绍在JAVA中读写二进制文件的解决方法。 一、什么是二进制文件 二进制文件是一种特殊类型的计算机文件,其存储格式是二进制的编码,包含了计算机能够读取和使用的信息。二进制文件可以存储各种形式的数据,包括图像、音频、视频、字体等。因为它们是以编程语言可读的方式编写的,二进制文件可以通过计算机程序进…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部