Springboot设置JWT与拦截器

1、安装依赖

在pom.xml中添加一下三个依赖

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

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>

2、application.yml配置

jwt.secret:JWT 密钥,用于对 JWT 进行签名和解密。
jwt.expire:JWT 的过期时间,以秒为单位。超过该时间,JWT 将被视为无效。
jwt.header:JWT 在请求头中的字段名称。

config:
  jwt:
    secret: hge_any_code
    expire: 30
    header: token

3、配置JWT

创建config文件夹
在这里插入图片描述

JwtConfig.java

import java.util.Date;

import io.jsonwebtoken.*;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "config.jwt", ignoreInvalidFields = true)
@Component
@Data
public class JwtConfig {
    private String secret;
    private Long expire;
    private String header;

    // 创建token值
    //setHeaderParam("typ", "JWT"):设置 JWT token 的头部参数,标识该 token 类型为 JWT。
    //setSubject(subject):设置 JWT token 的主题,即 sub 声明。
    //setIssuedAt(nowDate):设置 JWT token 的签发时间,即当前时间。
    //setExpiration(expireDate):设置 JWT token 的过期时间,即计算得到的过期日期。
    //signWith(SignatureAlgorithm.HS512, secret):使用 HMAC-SHA512 签名算法和密钥对 JWT 进行签名。
    public String createToken(String subject) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(subject)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    // 解析JWT并获取其中的声明信息。
    public Claims getTokenClaim(String token){
        try {
            return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedJwtException e) {
            throw new RuntimeException(e);
        } catch (MalformedJwtException e) {
            throw new RuntimeException(e);
        } catch (SignatureException e) {
            throw new RuntimeException(e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        }
    }

    // 获取 JWT token 中的subject声明信息。
    public String getSubject(String token) {
        return getTokenClaim(token).getSubject();
    }
}


TokenInterceptor.java

拦截器(Interceptor),用于在请求处理之前对请求进行拦截和处理。它的作用是验证请求中的令牌(token)是否有效,并且排除对登录接口的拦截。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private JwtConfig jwtConfig;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        if(uri.contains("login")){
            return true;
        }

        //处理token
        String token = request.getHeader(jwtConfig.getHeader());
        if(StringUtils.isEmpty(token)){
            token = request.getParameter(jwtConfig.getHeader());
        }

        if(StringUtils.isEmpty(token)){
            //返回401, token不能为空
            sendError(response,"token不能为空");
            return false;
        }

        try {
            jwtConfig.getTokenClaim(token);
        } catch (Exception e) {
//            throw new RuntimeException(e);
            //返回401. token失效,
            sendError(response,"token无效");
            return false;
        }
        return true;
    }

    private void sendError(HttpServletResponse response,String msg) throws IOException {
        response.setStatus(401);
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(msg);
    }
}

WebConfig.java

这段代码是一个配置类(WebConfig),用于配置拦截器(TokenInterceptor)的使用。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private TokenInterceptor tokenInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
    }
}

4、简单使用

User.java

public class User {
    private Integer id;
    private String username;
    private String password;
    private String nickname;
    private String address;
    private String email;
    private String phone;
    private String token;
}

UserController.java

    // 用户登录
    @PostMapping("/login")
    public Result toLogin(@RequestBody User user){
        // 查询数据库中是否存在匹配的用户记录,返回一个包含符合条件的用户列表
        List<User> list = userMapper.toLogin(user);
        // 从用户列表中获取第一个用户记录,假设它就是当前登录的用户。
        User currentUser = list.get(0);
        // 调用jwtConfig.createToken(currentUser.getUsername())方法创建一个JWT令牌。传入当前登录用户的用户名作为令牌的主题(Subject)
        String token = jwtConfig.createToken(currentUser.getUsername());
        // 将令牌设置到当前登录用户的token属性中
        currentUser.setToken(token);
        return Result.success("登录成功",currentUser);
    }

参考视频:https://www.bilibili.com/video/BV1wh4y1S7dr?p=42&vd_source=39c0a587ece2e4569d9e272c6181b901
p42

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值