什么是JWT?

目录

一、JWT详细介绍

1.JWT组成

2.JWT的优点

二、JWT使用示例


一、JWT详细介绍

1.JWT组成

JWT是一种轻量级的身份验证和授权机制,全称为JSON Web Token。它由三部分组成,分别是Header、Payload和Signature。

  1. Header:JWT头部通常由两部分组成,第一部分是声明类型,例如JWT,第二部分是声明所使用的算法,例如HMAC SHA256或者RSA等。

  2. Payload:Payload是JWT的第二部分,它包含了具体的用户信息,例如用户ID、用户名、角色等,也可以包含自定义的其他信息。Payload中的数据是以JSON格式进行编码,并且经过Base64URL编码。

  3. Signature:Signature是JWT的第三部分,它使用Header和Payload中的数据以及一个密钥来生成签名。签名的目的是保证消息没有被篡改,并且只能被服务器端识别和验证。

使用JWT进行身份验证和授权时,客户端在登录认证成功后会将JWT作为一个字符串返回给客户端,客户端之后每次请求都需要在HTTP头部中带上这个JWT字符串以进行身份验证和权限验证。因为JWT中已经包含有用户信息和签名,服务器端不需要再查询数据库或者其它存储来获取用户信息。

2.JWT的优点

  1. 去中心化验证:因为JWT本身已经包含了用户信息和签名,服务端不需要维护任何状态信息,从而实现去中心化验证。

  2. 跨语言支持:由于JWT是基于标准的JSON格式和Base64URL编码实现的,因此它可以在不同的平台和语言之间进行传输和解析。

  3. 安全性:在生成JWT签名时使用了加密算法,保证了JWT数据的安全性和完整性。

总之,JWT是一种简单、安全、便捷的身份验证和授权机制,在现代Web应用程序中得到广泛应用。

二、JWT使用示例


当用户使用登录凭证进行身份验证时,服务器通过生成一个JWT并将其发送给客户端完成身份验证的过程。

首先需要引入相关依赖:

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- JWT -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

然后定义一个JWT工具类,用于生成和解析JWT:

@Service
public class JwtUtils {

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

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

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("sub", userDetails.getUsername());
        claims.put("iat", new Date());
        claims.put("exp", new Date(System.currentTimeMillis() + expiration * 1000));

        return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
    }

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

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

    private boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    private Date getExpirationDateFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getExpiration();
    }
}

这里使用了Spring Security框架提供的UserDetails接口来表示用户信息,通过JwtUtils.generateToken()方法生成JWT字符串,并使用JwtUtils.getUsernameFromToken()方法从JWT中解析出用户名。validateToken()方法用于验证JWT是否合法,isTokenExpired()方法用于判断JWT是否过期。

最后,在登录成功后可以将JWT发送给客户端:

@RestController
public class LoginController {

    @Autowired
    private JwtUtils jwtUtils;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
        // 验证用户身份
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
        if (passwordEncoder.matches(loginRequest.getPassword(), userDetails.getPassword())) {
            // 生成JWT
            String token = jwtUtils.generateToken(userDetails);
            Map<String, Object> response = new HashMap<>();
            response.put("token", token);
            return ResponseEntity.ok(response);
        } else {
            throw new BadCredentialsException(" 验证失败,账号或密码不存在.");
        }
    }
}

在登录成功后,通过JwtUtils.generateToken()方法生成JWT,并将其封装在响应中返回给客户端。

猜你喜欢

转载自blog.csdn.net/weixin_59367964/article/details/130547134
jwt