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

以下是“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日

相关文章

  • SSH框架网上商城项目第11战之查询和删除商品功能实现

    SSH框架网上商城项目第11战之查询和删除商品功能实现 本文将详细讲解如何在SSH框架中实现查询和删除商品的功能。在此之前,需要确保该项目中已经实现了商品的增加和修改功能。 查询商品 在实现查询商品的功能前,首先需要在商品管理页面中添加查询表单。在JSP页面中添加如下代码: <form class="form-inline" act…

    Java 2023年6月16日
    00
  • 浅谈System.getenv()和System.getProperty()的区别

    标题:浅谈System.getenv()和System.getProperty()的区别 System.getenv() System.getenv() 方法返回一个表示环境变量的映射,其中key是变量名,value是变量值。该方法是在Java Runtime环境中调用操作系统的环境变量。 示例1: Map<String, String> env…

    Java 2023年6月15日
    00
  • 什么是对象引用?

    对象引用是 Java 中一种特殊的数据类型,用于存储对象在内存中的地址。在 Java 中,所有的对象都是在堆内中分配的,而对象引用则是在栈存中分配的对象引用可以用来访问对象的属性和方法。 以下是对象引用的完整使用攻略: 声明对象用 在 Java 中,使用名或接口名来声明对象引用。以下是一个声明对象引用的示例: public class ObjectRefer…

    Java 2023年5月12日
    00
  • Springboot – Fat Jar示例详解

    下面我来详细讲解“Springboot – Fat Jar示例详解”的完整攻略。 简介 首先介绍一下什么是Fat Jar。简单来说,它是一个可以包含应用程序所有依赖库的大型JAR文件,因此它也被称为可执行JAR文件。SpringBoot可以使用Maven或Gradle生成Fat Jar,其他构建工具也支持类似的功能。 在使用Fat Jar时,需要做的就是提供…

    Java 2023年5月19日
    00
  • 详解Spring Security中权限注解的使用

    详解Spring Security中权限注解的使用 概述 在使用Spring Security处理权限控制时,通常有两种方式: 基于URL拦截,对每个URL设置对应的权限 基于注解,对Controller或方法设置对应的权限 本篇攻略将详细讲解如何使用Spring Security中的权限注解进行权限控制。 Spring Security中的权限注解 Spr…

    Java 2023年6月3日
    00
  • Java excel数据导入mysql的实现示例详解

    Java excel数据导入mysql的实现示例详解 背景 在项目中,我们常常需要将Excel表格中的数据导入到MySQL数据库中,这是一种常用的数据导入方式。本文将介绍如何使用Java将Excel中的数据导入到MySQL数据库中,并提供两个示例供大家参考。 第一步:导入Excel相关的依赖 本示例中,我们使用Apache POI来操作Excel文件。在Ma…

    Java 2023年5月20日
    00
  • Java Pattern与Matcher字符串匹配案例详解

    Java Pattern与Matcher字符串匹配案例详解 一、背景介绍 在Java中,支持字符串的正则匹配。在字符串中,可以使用\d表示数字,\w表示字母数字下划线,\s表示空格或换行符等等特殊字符。而Java中提供了Pattern和Matcher类,用来实现正则表达式的匹配操作。 二、Pattern类 Pattern类是正则表达式编译后的表示形式。在Ja…

    Java 2023年5月23日
    00
  • Javaweb EL自定义函数开发及代码实例

    下面我将为您详细讲解“Javaweb EL自定义函数开发及代码实例”的完整攻略。 1. 什么是EL表达式 EL表达式全称是Expression Language,即表达式语言,它是JSP规范中的一个语言,用于简化JSP页面中的Java代码。EL表达式可以获取、设置、计算JavaBean的属性值,访问作用域中的变量及常量,调用JavaBean的方法等等。 2.…

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