JWT整合springboot实现token认证(代码实践)

    JWT的介绍和优缺点在此就不做说明了,相信这些网上的介绍比这里三言两语更加清楚,本文用于单点登录的,提高用户体验。

  • 生成token,返回给前端,前端可储存于cookie中,后面调用api接口时发送给后端
public static final long EXPIRATION_TIME = 3600_000; // 1 hour
public static final String SECRET = "secret";
public static final String TOKEN_PREFIX = "Bearer";
public static final String HEADER_STRING = "Authorization";
public static final String ROLE = "ROLE";

public static String getToken(String userRole) {
    HashMap<String, Object> map = new HashMap<>();
    map.put(ROLE, userRole);

    String jwt = Jwts.builder()
            .setClaims(map)  //playload部分
            .setSubject("主题")   // 主题
            .setIssuer("jay")     // 签发者
            .setIssuedAt(new Date()) // 签发时间
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) //过期时间
            .signWith(SignatureAlgorithm.HS512, SECRET) //签名
            .compact();
    return TOKEN_PREFIX + " " + jwt;
}
  •  解析token,取出playload部分的数据,以作对比
public static HttpServletRequest validateTokenAndAddUserIdToHeader(HttpServletRequest request) {
    String token = request.getHeader(HEADER_STRING);
    if (token != null) {
        // parse the token.
        try {
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                    .getBody();
            return new CustomHttpServletRequest(request, body);
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new TokenValidationException(e.getMessage());
        }
    } else {
        throw new TokenValidationException("Missing token");
    }
}
  •  解析部分一般在拦截器中处理,过期超时则返回登录页,token的过期时间也可使用以旧换新的方式,如App,每次打开App的时候刷新token的过期时间,这样就可以避免用户重复登录了。

 

类似文章推荐:https://www.jianshu.com/p/fe67b4bb6f2c

GitHub推荐:https://github.com/ZhongjunTian/spring-boot-jwt-demo/basic

 

 

好的,下面是完整的代码,您可以根据需要进行参考。 pom.xml: ```xml <dependencies> <!-- SpringBoot Web 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- JWT 依赖 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> </dependencies> ``` User.java: ```java public class User { private String username; private String password; // getter 和 setter 略 } ``` Result.java: ```java public class Result { private Integer code; private String message; private Object data; // getter 和 setter 略 public static Result success(Object data) { Result result = new Result(); result.setCode(200); result.setMessage("操作成功"); result.setData(data); return result; } public static Result failure(String message) { Result result = new Result(); result.setCode(500); result.setMessage(message); return result; } } ``` TokenUtil.java: ```java public class TokenUtil { private static final String SECRET_KEY = "your_secret_key"; // 密钥,可以自定义 // 生成token public static String generateToken(String subject) { Date now = new Date(); Date expiration = new Date(now.getTime() + 3600 * 1000); // 过期时间为1小时 return Jwts.builder() .setSubject(subject) .setIssuedAt(now) .setExpiration(expiration) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } // 验证token public static boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } // 从token中获取用户名 public static String getUsernameFromToken(String token) { Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody(); return claims.getSubject(); } } ``` TokenRequired.java: ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TokenRequired { } ``` TokenInterceptor.java: ```java @Component public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); // 从请求头中获取token if (StringUtils.isNotBlank(token) && TokenUtil.validateToken(token)) { // 验证通过,放行请求 return true; } else { // 验证失败,返回错误信息 response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); out.write("{\"code\":401,\"message\":\"未登录或登录已过期\"}"); out.flush(); out.close(); return false; } } } ``` UserController.java: ```java @RestController @RequestMapping("/user") public class UserController { @PostMapping("/login") public Result login(@RequestBody User user) { // 根据用户名和密码验证用户身份 if (userService.validateUser(user.getUsername(), user.getPassword())) { // 生成token并返回 String token = TokenUtil.generateToken(user.getUsername()); return Result.success(token); } else { return Result.failure("用户名或密码错误"); } } } ``` BookController.java: ```java @RestController @RequestMapping("/book") public class BookController { @GetMapping("/list") @TokenRequired // 自定义注解,用于标识需要登录认证的接口 public Result list() { List<Book> books = bookService.listBooks(); return Result.success(books); } } ``` WebMvcConfig.java: ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private TokenInterceptor tokenInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenInterceptor).addPathPatterns("/**").excludePathPatterns("/user/login"); } } ``` 其中,userService和bookService需要您自己实现。另外,为了简化代码,省略了Book类的定义。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值