您的位置:

使用Spring Boot整合JWT实现权限管理

一、什么是JWT

JSON Web Token (JWT)是一种安全的,开放的标准(RFC 7519),用于在双方之间传输信息。JWT包含了三部分,分别是Header,Payload和Signature。

Header通常包含两部分,算法和类型。算法指定加密算法,类型指定JWT类型,最常见的是JWT。

Payload是JWT最重要的部分,包含了Claim,Claim是要传输的数据,常见的有:iss(Issuer),iat(Issued At),exp(Expiration Time),sub(Subject),aud(Audience)等,Claim可以被加密。

Signature是将Header和Payload进行加密后的结果,Signature的作用是验证JWT的合法性。

二、在Spring Boot中使用JWT

1. 引入依赖

在pom.xml中添加以下依赖,这里使用的是io.jsonwebtoken:


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

2. 创建JWT工具类

我们需要创建一个工具类来生成和验证JWT,其中包含了JWT的生成和解析方法。


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtils {

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

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

    private Key key;

    @PostConstruct
    public void init() {
        key = Keys.hmacShaKeyFor(secret.getBytes());
    }

    public String generateToken(String username, String role) {
        Map
    claims = new HashMap<>();
        claims.put("username", username);
        claims.put("role", role);
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(key, SignatureAlgorithm.HS512)
                .compact();
    }

    public Claims parseToken(String token) {
        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
    }
}

   

3. 创建登录和鉴权接口

我们需要创建一个/login接口来进行用户登录,使用POST方法提交用户名和密码,之后验证用户信息,生成JWT并返回给客户端。还需要创建一个校验接口,使用JWT进行鉴权,如果JWT合法,返回200,否则返回401。


@RestController
public class AuthController {

    @Autowired
    private JwtUtils jwtUtils;

    @PostMapping("/login")
    public ResponseEntity
    login(@RequestBody User user) {
        if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) {
            String token = jwtUtils.generateToken(user.getUsername(), "admin");
            return ResponseEntity.ok(token);
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }

    @GetMapping("/auth")
    public ResponseEntity auth(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (StringUtils.isBlank(token)) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        try {
            Claims claims = jwtUtils.parseToken(token);
            String username = claims.get("username", String.class);
            String role = claims.get("role", String.class);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
    }
}

   

三、JWT的安全性

JWT的安全性很大一部分依赖于secret(加密密钥)的安全性,由于JWT是可解密的,所以secret在使用中要严格保密。另外,JWT也有一些缺点:

  • JWT不适合存储敏感数据。
  • 如果一个JWT被盗用,那么所有在有效期内的请求都是可以通过的,因此我们需要设置JWT的有效期尽量短。
  • JWT无法撤销,如果需要取消某个JWT的访问授权,需要等待其过期或者在服务端的黑名单上维护该JWT。

四、小结

通过本文,我们了解了JWT的结构和原理,掌握了在Spring Boot中使用JWT的方法,并介绍了JWT的安全性和一些限制。在实际的项目中,我们可以根据具体的需求选择合适的鉴权方式,在保障系统安全的前提下,提高用户体验。