Java中使用JWT生成Token进行接口鉴权实现方法

yizhihongxing

为了在Java中使用JWT生成Token进行接口鉴权,我们需要以下步骤:

1. 引入依赖

我们需要在项目中引入一个JWT依赖,例如Java JWT(https://github.com/auth0/java-jwt)。

Maven坐标如下:

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>

2. 生成Token

我们可以使用如下代码在Java中生成一个JWT Token:

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

public class JWTUtils {

    /**
     * 生成JWT Token
     * @param issuer    签发人
     * @param subject   主题
     * @param expireSeconds     过期时间,单位为秒
     * @param secret    密钥
     * @return  JWT Token
     */
    public static String generateToken(String issuer, String subject, long expireSeconds, String secret) {
        // 设置过期时间
        Date expireDate = new Date(System.currentTimeMillis() + expireSeconds * 1000);
        // 设置Header
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");
        // 生成Token
        String token = JWT.create().
            withHeader(header).
            withIssuer(issuer).
            withSubject(subject).
            withExpiresAt(expireDate).
            sign(Algorithm.HMAC256(secret));
        return token;
    }

}

其中,参数分别表示:

  • issuer:签发人
  • subject:主题
  • expireSeconds:过期时间,单位为秒
  • secret:密钥

使用JWT生成Token的算法一般采用HMAC加密算法,常见的有HMAC256和HMAC512。

为方便演示,我们在主函数中调用该方法并输出生成的Token:

public class Main {

    public static void main(String[] args) {
        String issuer = "test";
        String subject = "test-token";
        long expireSeconds = 3600;
        String secret = "my-secret";    // 这里应该放在配置文件中,不应该明文写在代码中

        String token = JWTUtils.generateToken(issuer, subject, expireSeconds, secret);
        System.out.println(token);
    }

}

输出的Token如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0Iiwic3ViIjoidGVzdC10b2tlbiIsImV4cCI6MTQ4MzAwNjc5MX0.9qCZ9UBpE5Jk8VTDeYACScJf_kwSp-CWr5zgG-Dgys4

3. 验证Token

我们可以使用如下代码在Java中验证一个JWT Token:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

public class JWTUtils {

    /**
     * 验证JWT Token
     * @param token JWT Token
     * @param secret    密钥
     * @return  是否验证通过
     */
    public static boolean verifyToken(String token, String secret) {
        try {
            // 创建验证器并设置Issuer和密钥
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret))
                .withIssuer("test")
                .build();
            // 验证Token
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}

验证Token的时候需要进行以下几项检验:

  • 是否有效(例如过期或者被篡改)
  • 是否由合法的签发人签发
  • 是否由合法的密钥签名

同样,我们在主函数中调用该方法并输出验证结果:

public class Main {

    public static void main(String[] args) {
        String issuer = "test";
        String subject = "test-token";
        long expireSeconds = 3600;
        String secret = "my-secret";    // 这里应该放在配置文件中,不应该明文写在代码中

        String token = JWTUtils.generateToken(issuer, subject, expireSeconds, secret);
        boolean result = JWTUtils.verifyToken(token, secret);
        System.out.println(result);
    }

}

输出的结果为:

true

示例1

我们可以将上述两个步骤结合起来并应用于一个简单的接口鉴权上,示例代码如下:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

    private String secret = "my-secret";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 获取Authorization Header
        String authorization = request.getHeader("Authorization");
        if (authorization == null || authorization.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        // 校验Token
        try {
            // 创建验证器并设置Issuer和密钥
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret))
                .withIssuer("test")
                .build();
            // 验证Token
            DecodedJWT jwt = verifier.verify(authorization);
            return true;
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
    }

}

该示例定义了一个拦截器,在请求进入Controller之前验证JWT Token的有效性。如果Token验证通过则放行,否则返回401 Unauthorized错误。

示例2

我们可以将JWT生成Token的代码应用于一个实际的业务场景中,例如在用户登录成功后生成一个Token并返回给客户端,客户端在后续请求中携带该Token以进行接口鉴权。

该示例利用Spring Boot框架搭建,代码如下:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody UserCredentials credentials) {
        // 根据用户名和密码从数据库中查询用户信息
        User user = userService.getUserByCredentials(credentials.getUsername(), credentials.getPassword());
        if (user == null) {
            return ResponseEntity.badRequest().body("用户名或密码错误");
        }

        // 生成Token并返回给客户端
        String issuer = "test";
        String subject = String.format("user-%d", user.getId());
        long expireSeconds = 3600;
        String secret = "my-secret";

        String token = JWTUtils.generateToken(issuer, subject, expireSeconds, secret);
        return ResponseEntity.ok(token);
    }

    @GetMapping("/profile")
    public ResponseEntity<User> getProfile(HttpServletRequest request) {
        // 从Token中解析出用户ID
        int userId = getUserIdFromToken(request);
        if (userId <= 0) {
            return ResponseEntity.badRequest().build();
        }

        // 根据用户ID从数据库中查询用户信息
        User user = userService.getUserById(userId);
        if (user == null) {
            return ResponseEntity.notFound().build();
        }

        // 返回用户信息
        return ResponseEntity.ok(user);
    }

    private int getUserIdFromToken(HttpServletRequest request) {
        // 从Authorization Header中解析出Token
        String authorization = request.getHeader("Authorization");
        if (authorization == null || authorization.isEmpty()) {
            return -1;
        }
        String token = authorization.substring("Bearer ".length());

        // 解析Token,获取UserId
        try {
            DecodedJWT jwt = JWT.decode(token);
            String subject = jwt.getSubject();
            int userId = Integer.parseInt(subject.split("-")[1]);
            return userId;
        } catch (Exception e) {
            return -1;
        }
    }

}

该示例中,客户端需要先调用“/user/login”接口进行登录,登录成功后服务器会返回一个JWT Token;客户端在后续的请求中需要在Authorization Header中携带该Token,例如:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0Iiwic3ViIjoidXNlci0xIiwiZXhwIjoxNDgzMDAyNjUwfQ.Ykn7x8K0Vwlf2kfjFMnLqmaA0O4SpnJHp3aY5oDtKZs

服务器在接收到请求后会校验Token的有效性,并从Token中解析出用户ID,再使用该用户ID从数据库中查询用户信息并返回给客户端。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中使用JWT生成Token进行接口鉴权实现方法 - Python技术站

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

相关文章

  • SpringBoot入门教程详解

    Spring Boot是一个非常流行的Java Web框架,它可以帮助开发者快速地构建Web应用程序。在本攻略中,我们将详细介绍如何使用Spring Boot,并提供两个示例来说明其用法。 以下是两个示例,介绍如何使用Spring Boot: 示例一:使用Spring Boot构建一个简单的Web应用程序 首先,我们需要在pom.xml文件中添加以下依赖: …

    Java 2023年5月15日
    00
  • 一文带你了解如何正确使用MyBatisPlus

    一文带你了解如何正确使用MyBatis Plus MyBatis Plus 是 MyBatis 的增强工具,在 MyBatis 的基础上,提供了更加便捷的方法和功能。本文将介绍如何正确使用 MyBatis Plus,包括安装、配置、使用和优化等方面。 安装和配置 在使用 MyBatis Plus 之前,需要进行一些准备工作,包括 Maven 依赖的配置和配置…

    Java 2023年5月20日
    00
  • Java全面分析面向对象之多态

    Java全面分析面向对象之多态 什么是多态 多态是面向对象语言中非常重要的一种处理方式。它允许在程序执行时根据实际对象类型选择要调用的方法。多态的实现基于继承、接口和重写。 多态的实现 多态的实现有两种方式: 1.继承 通过继承父类,在子类中重写父类的方法,达到不同类调用同一方法返回不同结果的效果。示例如下: class Animal { void move…

    Java 2023年5月26日
    00
  • SpringBoot整合freemarker的讲解

    SpringBoot整合Freemarker的完整攻略 1.1 添加依赖 使用SpringBoot整合Freemarker需要添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-star…

    Java 2023年5月19日
    00
  • SpringBoot可视化接口开发工具magic-api的简单使用教程

    SpringBoot可视化接口开发工具magic-api的简单使用教程 介绍 magic-api是一款SpringBoot可视化接口开发工具,可以让开发人员在图形化界面上快速构建RESTful API接口。其特点是通过简单的配置即可生成接口代码,支持对接口文档的在线管理和修改。 安装 首先,你需要在项目的pom.xml文件中添加magic-api的依赖: &…

    Java 2023年5月26日
    00
  • SpringBoot2 实现JPA分页和排序分页的案例

    下面是关于“SpringBoot2 实现JPA分页和排序分页的案例”的完整攻略: 1. 简介 SpringBoot是一款轻量级的Java开发框架,它可以用来构建各种类型的Web应用程序。其中,JPA(Java Persistence API)是Java EE规范的一部分,用于管理Java对象和关系型数据库之间的映射关系。JPA的分页和排序功能在实际开发中非常…

    Java 2023年6月2日
    00
  • java读取resource目录下文件的方法示例

    针对“java读取resource目录下文件的方法示例”,我将为你提供完整的攻略。请仔细阅读以下内容。 方法一:使用ClassLoader.getResource() ClassLoader.getResource() 方法可以帮助我们加载 classpath 中的资源,包括在 resource 目录下的文件。下面是一个简单的示例代码: public cla…

    Java 2023年5月20日
    00
  • Java面试题冲刺第三天–集合框架篇

    让我来为您详细讲解“Java面试题冲刺第三天–集合框架篇”的完整攻略。 一、前言 集合框架是Java编程中的重要一环,作为Java工程师,在面试中对集合框架要有深刻的理解。本篇文章将为您提供Java集合框架面试题的完整攻略,帮助您在面试中脱颖而出。 二、集合框架概述 集合框架是Java中的一组接口、实现类和算法,用于存储和操作一组对象。在Java编程中,集…

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