token拦截,springboot+vue

本文详细介绍了如何在Vue项目中设置token拦截,包括后端使用JavaJWT库生成和验证token,以及前端如何在axios请求中添加token验证,同时涵盖了注册、登录、拦截器配置和跨域问题的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设置token拦截的目的是为了让用户必须经过验证(比如账号密码)才能访问内部页面。
比如你写了"/login",“/register”,“/main"几个页面,那从逻辑上来说用户应该要先进行注册登陆才能访问”/main"页面。
但是使用vue写好这三个页面后你会发现,用户直接访问"/main"也是没有任何阻拦的。所以这个时候需要路由卫士和token拦截。
在注册和登陆通过的时候,会根据你的账号或密码生成一串字符串token,然后存在缓存里。
你想访问任何页面之前,会先验证你是否有token,如果没有,就把你送回"/login"页面,如果有,则你想去哪就去哪。

后端

  1. pom.xml里面添加token依赖
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.7.0</version>
        </dependency>
  1. token生成与验证的类
  • 应用方式:
    • 下面的代码就原封不动复制到后端某个地方,可以建个文件夹存放(为了方便这个文件夹就叫token文件夹了)。
  • 作用:
    • 这个是用于生成和验证token的。
    • 生成token:作用在后端的login方法里(下面有举例),你前端的登陆页面发送了登录请求,那么你后端有个登陆方法(比如就叫checkLogin)验证后,返回结果。现在你要在返回的结果里多带一条信息,就是token,那么token怎么来,需要调用这个TokenGenerate().generateToken(account)方法。
    • 验证token:作用在后端的拦截器中(下面有举例)。前端发送的请求要先经过拦截器,然后再到达各个controller。拦截器里会先设置token检验,那么就会用到这个TokenGenerate.verify(token)。
public class TokenGenerate
{

    private static final long EXPIRE_TIME= 15*60*1000;
    private static final String TOKEN_SECRET="tokenqkj";  //密钥盐
    public String generateToken(String username){
        String token = null;
        try{
            Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            token = JWT.create()
                    .withIssuer("auth0")
                    .withClaim("username", username)
                    .withExpiresAt(expiresAt)
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        }catch (Exception e){
            e.printStackTrace();
        }
        return token;
    }
    /**
     * 签名验证
     * @param token
     * @return
     */
    public static boolean verify(String token){
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("issuer: " + jwt.getIssuer());
            System.out.println("username: " + jwt.getClaim("username").asString());
            System.out.println("过期时间:      " + jwt.getExpiresAt());
            return true;
        } catch (Exception e){
            System.out.println("token:"+token);
            System.out.println("没通过");
            return false;
        }
    }
}
  1. 拦截器
  • 应用方式:
    • 下面的代码就原封不动复制到刚刚的token文件夹里。
  • 作用:
    • 这个就是上面说的拦截器。里面有一句request.getHeader("token")就是调用了上面的方法进行验证了。
//token拦截器,对拦截下的接口检查其的token是否符合只有
// 在提供一个有效的token时才能通过验证,否则给出认证失败的响应。
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{
        //Axios 发起跨域请求前,浏览器也会首先发起 OPTIONS 预检请求。检查服务器是否允许跨域访问。
        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            System.out.println("允许跨域访问");
            return true;
        }

        response.setCharacterEncoding("utf-8");
        String token = request.getHeader("token");
        if(token != null){
            boolean result = TokenGenerate.verify(token);
            if(result){
                System.out.println("通过拦截器");
                return true;
            }
        }
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("认证失败,错误码:50000");
        return false;
    }
}
  1. 入口拦截
  • 应用方式:
    • 下面的代码就原封不动复制到刚刚的token文件夹里。
    • 然后修改一处地方:注意我下面有两句
      excludePath.add("/registerCheck"); //注册
      excludePath.add("/loginCheck"); //登录
      
      这是我后端中的注册和登陆方法。在这里写上这两句意思就是,当用户访问这两个方法的时候不用验证token。
      这个很好理解,你登陆和注册的时候肯定是没有token的,token是你账号密码验证通过以后才会赋予你的信息。
      这两个要修改成你的注册登陆url。
//入口拦截,设置哪些接口需要拦截或不拦截(保护后端接口 防止未经授权的访问)
//只需要拦截本身就不会携带token的接口(例如登陆注册)
//因为登陆后网页的请求头就会携带token,此时我们需要进行token的验证,防止在未登陆时就可以进行其他操作
@Configuration
public class IntercepterConfig implements WebMvcConfigurer {
    private final TokenInterceptor tokenInterceptor;

//    构造方法
    public IntercepterConfig(TokenInterceptor tokenInterceptor) {
        this.tokenInterceptor = tokenInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //excludePathPatterns用来配置不需要拦截的接口(或者相当于功能)
        List<String> excludePath = new ArrayList<>();//List用来保存所有不需要拦截的路径
        excludePath.add("/registerCheck"); //注册
        excludePath.add("/loginCheck"); //登录
        //在登陆之后的网页中已经携带token,所以只需要放行登陆注册接口,
        //若放行其他接口,那么就相当于不需要登陆就可进行接口的使用



        registry.addInterceptor(tokenInterceptor)//添加名为tokenInterceptor的拦截器
                .addPathPatterns("/**") //指定拦截所有路径
                .excludePathPatterns(excludePath);//排除不需要拦截的路径
        WebMvcConfigurer.super.addInterceptors(registry);

    }
}
  1. 登陆函数
  • 应用方式:
    • 跟着代码里的注释改。
  • 作用:
    • 在用户账号密码验证正确时,返回一个信号并携带token。
	@GetMapping
    public String loginCheck(String account, String password)
    {
    	//用户传入了账号密码
        System.out.println("账号:" + account);
        System.out.println("密码:" + password);
        //在if括号里写你的方法,比如if (account.equals("admin") && password.equals("admin")),或者更复杂的数据库逻辑
        if (账号密码是正确的)
        {
        	//下面这一句用于生成token
            String token = new TokenGenerate().generateToken(account);
            //如果验证通过就返回token
            return token;
        } else
        {
        	//如果失败就没有token了,返回null。
            return null;
        }
    }

前端

  1. axios
  • 应用方式
    • 原封不动复制到前端的某个地方
    • 然后修改一处,注意到我下面有一句,url !== '/registerCheck' &&url !== '/loginCheck' && url !== '/logout',跟上面一样的意思,当用户访问这几个网址的时候不用验证token。即在安全性上排除了这几个网址。我排除了三个,注册,登录,注销。改成你自己的url。就是你后端的注册登陆网址是什么,这里就写什么。
import axios from 'axios'
// 创建axios实例
const instance = axios.create({
    baseURL: 'http://localhost:8082', // 设置后端接口地址(使用nginx代理了)
    timeout: 10000, // 设置请求超时时间
});
// 请求拦截器,在请求头中添加token
instance.interceptors.request.use(config =>
{
    // 获取请求的URL
    const {url} = config;
    // 如果请求的URL不是login、logout或register,则在请求头中添加token
    if (url !== '/initUser' &&url !== 'check' && url !== '/logout' && url !== '/register')
    {
        // 从localStorage中获取token
        const token = localStorage.getItem('token');
        if (token)
        {
            config.headers.Authorization = `Bearer ${token}`;
            config.headers.token = token;
            return config;
        }
    }
    return config;
}, error =>
{
    console.log(error)
    return Promise.reject(error);
});
// 响应拦截器
instance.interceptors.response.use(response =>
{
    // 在这里处理响应结果
    return response;
}, error =>
{
    // 在这里处理响应错误
    return Promise.reject(error);
});
// 导出axios实例
export default instance;

2.前端的注册登陆方法
我举个登陆的例子

//先import刚刚那个文件。"./filterAxios"需要改成你自己存放的位置
import axios from "./filterAxios"
//然后去请求后端的loginCheck
const res = axios.get("/loginCheck", {param:{{account: "xxx", password: "xxx"}}})
if(res.data === null)
	//说明登陆失败了,你可以弹个弹框啥的告诉用户
else
{
	//把token存到本地
	sessionStorage.setItem("token",res.data);
}

  1. 路由卫士
  • 应用方式
    • 原封不动复制到前端的router文件夹的index.js中,复制到最后一行(export default router)的上面!!!。不是最后一行的下面,是上面。
    • 然后修改一处if (to.name === "login" || to.name === "register"),改成你的注册和登陆页面的前端的url。
  • 作用
    • 这个是先确定你要去哪个网页,如果是注册/登陆网页,那你就直接去。如果不是注册登陆,那就得先验证你有没有token。有你才能去,否则你还是会被送回登陆页面。
router.beforeEach((to, from, next) =>
{
    console.log("taken:router:", sessionStorage.getItem('token'))
    if (!sessionStorage.getItem('token'))
    {
        if (to.name === "login" || to.name === "register")
            next();
        else
        {
            router.push('login')
        }
    }
    else
    {
        next();
    }
});

注意点

如果加了token以后前端出现了跨域错误“network error”,也有可能是后端出的错。
一度因为后端没报错,而前端报了错在前端苦苦寻找错误。
后端这家伙不爆错是因为在拦截器那里直接拦截了,直接将response设置为错误,返回给前端。

<think>好的,我现在需要帮助用户找到关于Java Spring BootVue.js整合的教程、示例、项目结构和最佳实践。首先,我应该回想用户提到的引用内容,看看里面有没有相关的信息。 根据用户提供的引用,引用[1]提到Spring Boot使用Spring Data JPA来持久化数据,引用[2]提到Spring Boot简化了配置和支持内嵌服务器,前端Vue.js。引用[3]和[4]具体提到了一个使用Spring BootVue.js构建的JWT认证应用,包括配置和Vue组件示例。引用[5]可能涉及项目实战和技术支持。 接下来,我需要整理这些信息,构建一个结构清晰的回答。可能需要包括项目结构、前后端交互方式、技术整合步骤、最佳实践以及示例代码。同时,用户可能需要了解如何搭建这样的项目,所以分步骤说明会比较好。 需要注意用户提到的系统级指令,比如数学公式的格式,但这个问题可能不涉及数学内容,所以可能不需要处理这点。另外,要生成相关问题,可能需要围绕整合中的关键点提问,比如认证、部署、优化等。 还需要检查是否引用了正确的来源,比如引用[3]和[4]中的JWT配置和Vue组件代码,引用[2]中的Spring Boot特性。确保回答中的引用标识正确,例如在提到前后端分离或配置时引用相应的来源。 可能存在的问题是,如何将前后端项目结构组织在一起,是否需要分开仓库或者放在同一项目下。根据引用[4]中的代码结构,前端Vue组件放在src/components,可能意味着前后端在一个项目里,但实际最佳实践通常是前后端分离,独立项目,通过API交互。所以需要澄清这一点,可能用户需要了解两种方式的优缺点。 另外,用户可能需要示例代码,比如Spring Boot的控制器如何提供API,Vue如何调用这些API。引用[4]中的Vue组件展示了调用后端API的示例,可以引用这一点。 在最佳实践中,要提到安全措施,比如JWT认证(引用[3]),配置管理,错误处理等。同时,部署方面,引用[2]提到内嵌服务器,可能涉及如何打包和部署前后端应用。 总结回答的结构应该是: 1. 项目结构:前后端分离,各自独立项目或同一项目下的不同模块。 2. 技术整合步骤:后端Spring Boot设置REST API,前端Vue调用API,使用JWT认证。 3. 示例代码:引用已有的代码片段,如Vue组件和Spring Boot配置。 4. 最佳实践:安全、配置、错误处理、部署等。 5. 相关问题:围绕整合中的挑战、优化、扩展等提问。 需要确保引用正确,比如在提到JWT时引用[3],在提到项目结构时引用[4],在Spring Boot配置时引用[2]等。 现在组织这些内容,用中文清晰回答,并生成相关问题。</think>### Java Spring BootVue.js整合指南 #### 1. 项目结构 典型的整合方案采用**前后端分离架构**,后端使用Spring Boot提供REST API,前端通过Vue.js调用接口并渲染页面。 - **后端结构**: - `src/main/java`:存放Spring Boot控制器、服务类等,如`UserController.java` - `src/main/resources/application.properties`:配置数据库、JWT密钥等[^3] - **前端结构**(独立项目): - `src/components`:Vue组件(如`HelloWorld.vue`)[^4] - `src/router`:路由配置 - `src/api`:封装后端API请求 > **两种部署方式**: > 1. **独立部署**:前后端分别打包,前端通过Nginx部署,后端通过Jar包运行[^2] > 2. **整合部署**:将Vue编译后的静态文件放入Spring Boot的`src/main/resources/static`目录,通过内嵌Tomcat统一服务[^2] --- #### 2. 技术整合步骤 **步骤1:后端API开发** ```java // UserController.java @RestController @RequestMapping("/api") public class UserController { @GetMapping("/data") public ResponseEntity<Map<String, String>> getData() { return ResponseEntity.ok(Map.of("message", "Hello from Spring Boot!")); } } ``` **步骤2:前端调用API** 引用[4]中的Vue组件演示了如何通过`fetch`调用后端接口: ```javascript // HelloWorld.vue methods: { fetchData() { fetch('/api/data') .then(response => response.json()) .then(data => { this.message = data.message; }); } } ``` **步骤3:JWT认证整合** - 后端添加Spring Security依赖,配置JWT过滤器[^3] - 前端在请求头中携带`Authorization: Bearer <token>` --- #### 3. 最佳实践 1. **接口规范** - 使用统一响应格式,如`{ code: 200, data: {}, message: "" }` - 启用CORS配置避免跨域问题 2. **安全优化** - 敏感配置(如数据库密码、JWT密钥)通过环境变量注入[^3] - 接口权限控制(基于角色的访问控制) 3. **性能优化** - 前端使用Axios替代原生`fetch`,增加请求拦截器 - 后端启用缓存(如Redis) --- #### 4. 完整示例项目 参考引用[3][^3]的JWT认证实现: - **后端配置**: ```properties # application.properties spring.security.user.name=admin spring.security.user.password=admin jwt.secret=your-256-bit-secret ``` - **前端交互**:登录后存储Token至LocalStorage ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值