详解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多线程之CAS算法实现线程安全

    Java多线程之CAS算法实现线程安全攻略 什么是CAS算法 CAS是英文单词Compare And Swap的缩写。CAS算法是一种无锁算法,它通过三个操作数:内存地址、旧的预期值和新值,当且仅当预期值和内存地址值相同时,才会将内存地址值更新为新值。CAS算法属于乐观锁技术的一种,线程不会阻塞,而是采用一种自旋的方式去检查更新,直到成功为止。 CAS算法的…

    Java 2023年5月19日
    00
  • Java结构型模式之桥接模式详解

    Java结构型模式之桥接模式详解 概述 桥接模式是一种用于软件设计的结构型模式,最早由著名的设计模式书籍《设计模式:可复用面向对象软件的基础》中的Gamma等人提出。 桥接模式的主要目的是将抽象部分和实现部分分离,分别放在不同的类层次结构中,从而实现它们之间的独立变换。通过分离抽象部分和实现部分,可以使它们可以相对独立地变化,从而可以大大降低它们之间的耦合度…

    Java 2023年5月20日
    00
  • java springmvc乱码解决归纳整理详解

    Java Spring MVC 是一种非常流行的 Java Web 开发框架。它提供了许多特性和强大的功能,但是在处理中文文本等需要编码转换的场景中,往往会遇到乱码问题。本篇攻略将详细讲解如何解决 Java Spring MVC 中的乱码问题。 1. 请求编码解决 一般情况下,在处理 HTTP 请求时,浏览器会设置请求的编码格式。但是如果请求头中没有指定编码…

    Java 2023年5月20日
    00
  • JSP教程(一)

    下面是“JSP教程(一)”的完整攻略。 标题 在文档开头加入标题,以便读者能够了解该文档的内容。 # JSP教程(一) 简介 在简短的几句话中介绍文档的内容和目标用户。 本文档将介绍什么是JSP,以及JSP的结构和基本语法。本文适合那些对Java Web开发有基本了解的读者阅读。 什么是JSP? JSP(Java Server Pages)是一种Java技术…

    Java 2023年6月15日
    00
  • springboot使用外置tomcat启动方式

    下面是关于“springboot使用外置tomcat启动方式”的完整攻略。 1. 准备工作 在开始使用外置tomcat启动SpringBoot应用之前,需要先进行一些准备工作。 1.1 确认Tomcat版本 确保Tomcat版本符合SpringBoot版本要求。可以通过SpringBoot官方文档中的 Supported Application Server…

    Java 2023年5月19日
    00
  • java使用反射创建并操作对象的方法

    Java反射可以在运行时获取类的信息以及动态操作对象,使用反射创建并操作对象的方法如下: 1.获取Class对象 使用反射创建对象,首先需要获取Class对象,有如下三种方式:- 调用Class.forName()- 通过类名.class获取- 使用对象.getClass()方法获取Class对象 示例1:调用Class.forName()方法获取Class…

    Java 2023年5月26日
    00
  • 深入理解Java new String()方法

    深入理解Java new String()方法 在Java中,String类是经常使用的类之一。在实际开发中,我们可能需要使用到String类中的构造函数new String(),它有许多不同的使用方式。在本篇文章中,我们将深入探讨new String()方法。 什么是new String()方法? new String()是String类的构造函数之一,它…

    Java 2023年5月26日
    00
  • JAVA开发环境搭建教程

    JAVA开发环境搭建教程 简介 本教程将指导你如何搭建JAVA开发环境,包括JDK的安装、环境变量的配置以及常用IDE的下载和配置。 JDK的安装 JDK是JAVA开发所必须的基础环境,我们需要先安装JDK。以下是安装步骤: 下载JDK安装包,可到Oracle官网下载对应平台的JDK。 执行安装包,一路按默认设置即可完成安装,记住安装的路径。 环境变量的配置…

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