SpringBoot使用JWT实现登录验证的方法示例

yizhihongxing

以下是“SpringBoot使用JWT实现登录验证的方法示例”的完整攻略:

1. 什么是JWT?

JWT(JSON Web Token)是由JSON生成的令牌,通常用于身份验证和授权。它是一个开放标准(RFC 7519),通过在不同方之间安全地传输声明来作为JSON Web签名(JWS)或JSON Web加密(JWE)的方式。在Spring Boot中使用JWT可以达到一定的安全验证。

2. JWT的结构

一个JWT令牌由3个部分组成:

头部(Header)

头部包含了令牌的元数据,它包括了算法和类型等信息。例子:

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

负载(Payload)

负载包含了一些声明信息,比如用户ID,有效期时间等等。例子:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

签名(Signature)

签名是对头部和负载进行签名的结果。根据头部中声明的算法和一个密钥,可以通过特殊的算法来生成一个签名。

3. Spring Boot使用JWT实现登录验证的方法示例

3.1 创建Spring Boot项目

首先,我们需要创建一个Spring Boot 项目。可以使用Spring Initializr 或是手动创建。

3.2 添加依赖

然后,我们需要添加依赖,包括 Spring Security 和JWT。在maven中添加以下依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-test</artifactId>
   <scope>test</scope>
</dependency>

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

3.3 实现UserDetailsService

接下来,我们需要实现一个Spring Security的UserDetailsService接口,用来根据用户名获取用户信息:

/**
 * Spring Security UserDetailsService 实现类
 * 用于获取用户信息
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
        } else {
            return JwtUserFactory.create(user);
        }
    }
}

3.4 创建JwtUtils

然后,我们需要创建一个JwtUtils类,用来生成和解析JWT令牌:

/**
 * JWT工具类,用来生成和解析JWT
 */
@Component
public class JwtUtils {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expires}")
    private long expiration;

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        claims.put(Claims.SUBJECT, userDetails.getUsername());
        claims.put(Claims.ISSUED_AT, new Date());
        return generateToken(claims);
    }

    public String generateToken(Map<String, Object> claims) {
        Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000);
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }

    public String getUsernameFromToken(String token) {
        return getClaimsFromToken(token).getSubject();
    }

    public Date getExpirationDateFromToken(String token) {
        return getClaimsFromToken(token).getExpiration();
    }

    public Claims getClaimsFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

    public boolean validateToken(String token, UserDetails userDetails) {
        String username = getUsernameFromToken(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    public boolean isTokenExpired(String token) {
        Date expirationDate = getExpirationDateFromToken(token);
        return expirationDate.before(new Date());
    }
}

3.5 实现AuthenticationController

最后,我们需要实现一个AuthenticationController,用来处理登录认证,并生成JWT令牌:

@RestController
@RequestMapping("/auth")
public class AuthenticationController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtUtils jwtUtils;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) throws AuthenticationException {

        // 验证用户和密码
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, loginRequest.getPassword());
        authenticationManager.authenticate(authenticationToken);

        // 生成JWT令牌
        String token = jwtUtils.generateToken(userDetails);
        return ResponseEntity.ok(new AuthenticationResponse(token));
    }
}

class LoginRequest {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

class AuthenticationResponse {

    private final String token;

    public AuthenticationResponse(String token) {
        this.token = token;
    }

    public String getToken() {
        return token;
    }
}

到此处,整个登录认证的流程就完成了。

3.6 示例使用

3.6.1 登录

使用POST方式请求URL:"/auth/login",传递参数如下:

{
    "username":"admin",
    "password":"admin"
}

请求成功,将会得到类似如下的响应:

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTYwNTQyMjQwNiwiZXhwIjoxNjA1NDIzMjA2fQ.om7Bvu_ikvUT6eUrJ67x9yvLsaJk3de-5Lb5mzyZ7fg"
}

3.6.2 调用受保护接口

修改我们的UserController:

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

    @GetMapping("/info")
    public String getInfo(@AuthenticationPrincipal JwtUserDetails auth) {
        return "username: " + auth.getUsername() + ", id: " + auth.getId();
    }
}

提供一个受保护的接口"/user/info",在方法参数中使用 "@AuthenticationPrincipal JwtUserDetails" 注解,即可获取当前登录用户的信息。

使用POST方式请求URL:"/auth/login"获取到的Token,构造一个新的Get请求Header: "Authorization",值为:"Bearer {token}",其中 {token} 为从服务器获取到的 Token 串,发送到URL:"/user/info"即可获取当前用户的信息。

这样,我们就实现了一个简单的使用JWT的Spring Boot登录认证流程。

4. 总结

以上就是实现基于SpringBoot + JWT的登录认证流程的详细攻略。JWT具有可扩展性、轻量级、安全性高等特点,在实际开发中也是比较常见的身份验证方式之一。通过以上的方式,你也可以轻松实现一个SpringBoot + JWT的登录认证功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot使用JWT实现登录验证的方法示例 - Python技术站

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

相关文章

  • Java基础学习之接口详解

    Java基础学习之接口详解 概述 在Java中,接口(interface)是一个相对抽象的概念,它并不是任何一个具体对象的实例,而是一种特殊的类,可以理解为是一种规范,定义了一些方法和属性,但是并不具体实现,因此需要由其他类去实现这些方法和属性。在下文中,我们将详细讲解接口的基本概念、定义方式及使用方法。 接口的定义 在Java中,接口使用interface…

    Java 2023年5月26日
    00
  • Python 实现一个颜色色值转换的小工具

    下面是详细的攻略: 1. 所需工具和材料 Python编程环境,比如Anaconda、PyCharm等 colorsys模块(Python标准库中已经包含) 学习Python基础知识 2. 实现思路 使用colorsys模块可以将RGB颜色值转换为HSV和HSL颜色值。具体实现思路如下: 接收输入的RGB颜色值,并将它们转换为0到1之间的数值。 使用colo…

    Java 2023年5月26日
    00
  • SpringBoot整合mybatis通用Mapper+自定义通用Mapper方法解析

    下面我将详细讲解“SpringBoot整合mybatis通用Mapper+自定义通用Mapper方法解析”的完整攻略。 一、什么是通用Mapper 通用Mapper是Mybatis官方提供的一个插件,它可以自动化生成Mybatis的基本CRUD方法,避免了开发人员重复编写大量类似的Sql代码的繁琐工作。这样能够大大提高开发效率,让我们把重点放在业务逻辑上。 …

    Java 2023年5月26日
    00
  • Java中两种基本的输入方式小结

    Java中有两种基本的输入方式,分别为键盘输入和文件输入。以下是两种方式的详细讲解。 键盘输入 1. 使用Scanner类 使用Scanner类可以很方便地接受键盘输入。示例如下: import java.util.Scanner; public class KeyboardInput { public static void main(String[] a…

    Java 2023年5月26日
    00
  • web.xml SpringBoot打包可执行Jar运行SpringMVC加载流程

    web.xml SpringBoot打包可执行Jar运行SpringMVC加载流程 在 SpringBoot 中,我们可以使用可执行 Jar 包来运行我们的应用程序。本文将详细讲解如何使用 web.xml 文件来配置 SpringMVC,并将其打包为可执行 Jar 包。 1. 创建 SpringBoot 项目 首先,我们需要创建一个 SpringBoot 项…

    Java 2023年5月18日
    00
  • Java环境配置原理全面解析

    这里是关于Java环境配置原理全面解析的详细攻略。 简介 Java是一种跨平台编程语言,需要安装Java开发工具包(JDK)才能进行编码,因此在进行Java编程之前必须进行Java环境的安装和配置。 Java环境配置的主要内容包括: 安装JDK 配置环境变量 本文将逐一介绍这两个过程,并附带两个实际的安装示例。 安装JDK JDK的安装需要从Oracle官网…

    Java 2023年5月24日
    00
  • JDK14的新特性NullPointerExceptions的使用

    下面是详细讲解“JDK14的新特性NullPointerExceptions的使用”的完整攻略。 什么是NullPointerExceptions NullPointerExceptions 是 Java 程序中最常见的错误之一,它通常会在代码中使用空引用时发生。在 JDK14 中,对于这个问题已经进行了一些新的改进,我们可以更加方便地处理这个问题。 如何使…

    Java 2023年5月27日
    00
  • Java语言中flush()函数作用及使用方法详解

    Java语言中flush()函数作用及使用方法详解 1. flush()函数的作用 在Java语言中,flush()函数用于清空输出流缓冲区,强制将缓冲区的内容输出到目标位置(比如文件、网络等)。具体来说,flush()函数将输出流中的所有缓冲数据都写入到目标位置,同时清空缓冲区,保证数据能够及时地被输出到目标位置。在输出流关闭之前,我们经常需要调用flus…

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