使用springboot解释什么是jwt

使用springboot解释什么是jwt

在这里插入图片描述

简介

JWT全称为JSON Web Token,是一种基于JSON格式的轻量级的身份认证和授权机制。它由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature),通常使用点号(.)将这三部分连接起来形成一个字符串。其中,头部通常包含加密算法和token类型等信息,载荷通常包含用户信息和权限等数据,签名则是对头部和载荷的加密结果。JWT常用于Web应用的身份认证和授权,客户端通过在请求头中携带JWT向服务器进行身份验证并获取资源。由于JWT是无状态的,因此可以实现跨域请求和分布式系统的身份认证和授权。

组成结构

jwt令牌由三个部分组成,分别是:

header:令牌头部,记录了整个令牌的类型和签名算法
payload:令牌负荷,记录了保存的主体信息,比如你要保存的用户信息就可以放到这里
signature:令牌签名,按照头部固定的签名算法对整个令牌进行签名,该签名的作用是:保证令牌不被伪造和篡改
它们组合而成的完整格式是:header.payload.signature
下面是一个具体的JWT示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

这个JWT由三部分组成,用点号(.)分隔:

  • 头部(Header):eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

  • 载荷(Payload):eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

  • 签名(Signature):SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 其中,头部和载荷都是使用Base64Url编码后的JSON字符串,可以使用Base64Url解码得到原始的JSON数据。例如,上面的头部可以解码为以下JSON格式:

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

这表示该JWT使用HS256算法进行签名,并且类型为JWT。而载荷可以解码为以下JSON格式:

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

这表示该JWT的主题为"1234567890",用户名为"John Doe",签发时间为2018年1月18日 22:23:42。而签名则是对头部和载荷的加密结果,可以使用密钥进行解密得到原始数据。

在springboot中的作用

在Spring Boot中使用JWT的具体案例如下:

1. 添加依赖 在pom.xml文件中添加以下依赖
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
2. 配置JWT 在Spring Boot的配置文件中配置JWT的相关参数,例如密钥、过期时间等:
jwt:
  secret: mySecretKey
  expiration: 3600
3. 创建JWT工具类 创建一个JWT工具类,用于生成和解析JWT:
@Component
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) {
        String username = getUsernameFromToken(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }
    private boolean isTokenExpired(String token) {
        Date expirationDate = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getExpiration();
        return expirationDate.before(new Date());
    }
}

这个工具类中包含了生成JWT、解析JWT和校验JWT的方法。其中,生成JWT时将用户信息存储在载荷中,解析JWT时可以获取到载荷中存储的用户信息。

4. 创建控制器 创建一个控制器,用于生成JWT和验证JWT:
@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtUtils jwtUtils;
    @PostMapping("/login")
    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = jwtUtils.generateToken((UserDetails) authentication.getPrincipal());
        return ResponseEntity.ok(new JwtResponse(jwt));
    }
    @GetMapping("/user")
    public ResponseEntity<?> getUser(@RequestHeader("Authorization") String token) {
        String username = jwtUtils.getUsernameFromToken(token.substring(7));
        User user = new User(username);
        return ResponseEntity.ok(user);
    }
}

这个控制器中包含了一个登录接口和一个获取用户信息的接口。登录接口会校验用户名和密码,并生成JWT返回给客户端;获取用户信息的接口会根据JWT中的用户信息返回相应的用户信息。

5. 测试接口 使用Postman等工具测试接口
  • 登录接口:发送POST请求到/auth/login,请求体为JSON格式的登录信息:
{
  "username": "admin",
  "password": "admin"
}

如果登录成功,会返回如下格式的JWT

{
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTYzOTU5Mzg5MiwiZXhwIjoxNjM5NjAzODkyfQ.7jKbW8uZwVnNpDxgFv7Ll-W1eQ2m9y9XzjvP8vejJZw"
}

获取用户信息接口:发送GET请求到/auth/user,请求头中携带JWT:

Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTYzOTU5Mzg5MiwiZXhwIjoxNjM5NjAzODkyfQ.7jKbW8uZwVnNpDxgFv7Ll-W1eQ2m9y9XzjvP8vejJZw

如果JWT有效,会返回如下格式的用户信息:

{
  "username": "admin"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不可大东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值