09. Springboot3+vue3实现JWT登录鉴权

1214 字约 3 分钟读完7151 次阅读更新于 2026/5/3

为什么要做鉴权?

因为管理系统的数据是敏感的,隐私的,而且一般每个角色权限是不同的,所以必须在数据的增删改查操作的时候对访问的用户做权限验证。

什么是 JWT?

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络应用间安全地传输信息。它以紧凑且自包含的方式,通过 JSON 对象在各方之间传递经过验证的信息。

JWT 由三部分组成,用 . 分隔:

Header(头部):包含算法(如 HMAC SHA256 或 RSA)和令牌类型(固定为 JWT)。

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

Payload(负载):携带声明(如用户身份、权限、有效期等),分为三类:

  • Registered claims(预定义字段,如 exp 过期时间、iss 签发者)。
  • Public claims(公开自定义字段,需避免冲突)。
  • Private claims(私有字段,双方协商)。
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
  • Signature(签名):对头部和负载的签名,防止数据篡改。

集成 JWT

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

生成 Token

/**
 * 生成token
 */
public static String createToken(String data, String sign) {
    return JWT.create().withAudience(data) // 将 userId-role 保存到 token 里面,作为载荷
            .withExpiresAt(DateUtil.offsetDay(new Date(), 1)) // 1天后token过期
            .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥, HMAC256算法加密
}

在登录接口返回 token

AdminService 的 login 方法

// 创建token并返回给前端
String token = TokenUtils.createToken(dbAdmin.getId() + "-" + "ADMIN", dbAdmin.getPassword());
dbAdmin.setToken(token);

Token 的格式

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxLUFETUlOIiwiZXhwIjoxNzQwNDAxOTI1fQ.zp2dX3A-Iv5lTv2seejmnHA24qQUPX0hXeXxHmiCZsI

JWT 拦截器

WebConfig

package com.example.common;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login", "/register");
    }

    @Bean
    public JWTInterceptor jwtInterceptor() {
        return new JWTInterceptor();
    }

}

出现 401 错误,您无权限访问数据怎么办?

在 vue 的 request.js 的拦截器里面 加上统一的请求头 token

看网络请求,出现了 token

request.js 的代码示例

import axios from "axios";
import {ElMessage} from "element-plus";
import router from "@/router/index.js";

const request = axios.create({
    baseURL: 'http://localhost:9999',
    timeout: 30000  // 后台接口超时时间
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    let user = JSON.parse(localStorage.getItem('code_user') || '{}')
    config.headers['token'] = user.token
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        if (res.code === '401') {
            ElMessage.error(res.msg)
            router.push('/login')
        } else {
            return res
        }
    },
    error => {
        if (error.response.status === 404) {
            ElMessage.error('未找到请求接口')
        } else if (error.response.status === 500) {
            ElMessage.error('系统异常,请查看后端控制台报错')
        } else {
            console.error(error.message)
        }
        return Promise.reject(error)
    }
)

export default request

解析 Token 获取用户信息

在 service 方法里面 获取当前的登录用户信息

Account currentUser = TokenUtils.getCurrentUser();