基于SpringBoot-Vue框架使用JWT令牌鉴权

JWT令牌鉴权是一种基于令牌的身份验证机制,它使用JSON Web Token(JWT)来验证用户的身份。在使用SpringBoot-Vue框架开发应用时,可以使用JWT令牌鉴权来保护接口的访问,并实现用户的身份验证和权限控制。

以下是基于SpringBoot-Vue框架使用JWT令牌鉴权的步骤:

引入依赖:

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
         <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.7</version>
        </dependency>

生成JWT令牌:

在用户登录成功后,服务器生成一个JWT令牌,其中包含用户的身份信息和其他相关信息。可以使用Java的JWT库(如jjwt)来生成JWT令牌。

import cn.hutool.core.util.StrUtil;
import com.computer.pojo.User;
import com.computer.service.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.Map;

@Slf4j
@Component
public class JwtTokenUtils {

    private static String signKey = "heima"; // 加密规则
    private static Long expire = 43200000L; // 有效期

    private static UserService staticUserService;
    @Resource
    private UserService userService;

    @PostConstruct
    public void setUserService(){
        staticUserService = userService;
    }

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }

    /**
     * 获取当前登录用户信息
     * @return
     */
    public static User getCurrentUser(){
        String token = null;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token = request.getHeader("token");
            if (StrUtil.isBlank(token)){
                // token为空,去参数中查找
                token = request.getParameter("token");
            }
            if (StrUtil.isBlank(token)){
                log.error("获取当前登录的用户信息失败, token={}",token);
                return null;
            }
            // 解析token,获取用户id
            Integer nameId = (Integer) parseJWT(token).get("id");
            return staticUserService.findById(nameId);
        } catch (Exception e) {
            log.error("获取当前登录的用户信息失败, token={}",token, e);
            return null;
        }
    }
}

将JWT令牌返回给前端:

将生成的JWT令牌返回给前端,前端可以将其保存在本地。

localStorage.setItem("user", JSON.stringify(res.data));

前端发起请求时携带JWT令牌:

前端在每次请求接口时,在请求头中携带JWT令牌。可以使用axios等AJAX库来发送带有JWT令牌的请求。

 const user = localStorage.getItem("user");
    if (user){
        config.headers['token'] = JSON.parse(user).token;  // 设置请求头
    }

后端验证JWT令牌:

后端在接收到请求时,需要验证JWT令牌的有效性。可以编写一个拦截器或过滤器来实现JWT令牌的验证。验证的过程包括解析JWT令牌、验证签名和验证令牌的相关信息(如过期时间)。

import cn.hutool.core.util.StrUtil;
import com.computer.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1、获取token
        String token = request.getHeader("token");
        if (StrUtil.isBlank(token)){
            // token为空,去参数中查找
            token = request.getParameter("token");
        }
        // 2、开始认证
        if (StrUtil.isBlank(token)){
            throw new CustomException("无token,请重新登录");
        }
        // 获取token中的adminID
        User user;
        try {
            user = JwtTokenUtils.getCurrentUser();
        } catch (Exception e) {
            String errMsg = "token验证失败,请重新登录";
            log.error(errMsg + ",token=" + token, e);
            throw new CustomException(errMsg);
        }
        if (user == null){
            throw new CustomException("用户不存在。请重新登录");
        }
        return true;
    }
}

 自定义拦截器

public void addInterceptors(InterceptorRegistry registry) {
        // 拦截使用请求
        registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**")
                // 排除登录、注册
                .excludePathPatterns("/api/register")
                .excludePathPatterns("/api/login");
    }

鉴权结果返回给前端:

在JWT令牌验证成功后,后端可以将鉴权结果返回给前端。可以返回用户信息或鉴权成功的状态码,前端可以统一处理返回结果。

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        // response.data即为后端返回的Result
        let res = response.data;
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string'){
            res = res ? JSON.parse(res) : res
        }
        return res;
    }, error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值