vue3-13

token可以是后端api的访问依据,一般绝大多数时候,前端要访问后端的api,后端都要求前端请求需要携带一个有效的token,这个token用于用户的身份校验,通过了校验,后端才会向前端返回数据,进行相应的操作,如果没有通过校验,后端则做其他处理。

之前后端代码并没有对前端请求进行token校验,之前的后端src/main/resources/application.properties的文件


spring.datasource.url=jdbc:mysql://localhost:3306/server?serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=1234spring.sql.init.mode=always
spring.sql.init.encoding=UTF-8interceptor.key=abcdefghijklmnopqrstuvwxyz0123456789
#NONE:不拦截
interceptor.mode=NONE
#拦截白名单,因为在登录的时候是没有token的,所以没有进行拦截校验
interceptor.whiteList=/api/loginJwt,/api/loginSessionlogging.level.com.lala.mapper=debug
spring.jackson.default-property-inclusion=non_null
mybatis.configuration.map-underscore-to-camel-case=true

src/main/java/com/lala/controller/LoginInterceptor.java文件

package com.lala.controller;import com.lala.service.SecretKeyService;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.security.SignatureException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.stream.Stream;public class LoginInterceptor implements HandlerInterceptor {@Autowiredprivate SecretKeyService secretKeyService;//@Value将外部的值动态注入到Bean中/*这段代码是Spring框架中的一部分,用于从属性文件中注入值。@Value 注解用于将属性文件中的值注入到字段中。在这个例子中,它试图从属性文件中获取一个名为 interceptor.mode 的值,并把它赋给 InterceptorMode 类型的 interceptorMode 字段。如果没有找到这个属性,那么 InterceptorMode.NONE 将被赋给 interceptorMode。*/@Value("${interceptor.mode}")private final InterceptorMode interceptorMode = InterceptorMode.NONE;@Value("${interceptor.whiteList}")private String[] interceptorWhiteList;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {//浏览器在跨域的时候,可能发送一个OPTIONS请求,对这个请求不做拦截,或者是白名单的请求也不做拦截if ("OPTIONS".equals(request.getMethod()) ||Stream.of(interceptorWhiteList).anyMatch(p -> p.equals(request.getRequestURI()))) {return true;}switch (interceptorMode) {case JWT -> {String token = request.getHeader("Authorization");System.out.println("token=" + token);if (token == null) {//未携带 tokenthrow new Exception401("未携带 token");}try {SecretKey secretKey = secretKeyService.getSecretKey();//根据secretKey生成tokenJwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);} catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | SignatureException |IllegalArgumentException e) {//校验 token 失败throw new Exception401("校验 token 失败");}}case SESSION -> {Object user = request.getSession().getAttribute("user");if (user == null) {//校验 session 失败throw new Exception401("校验 session 失败");}}case NONE -> {return true;}}return true;}enum InterceptorMode {NONE, JWT, SESSION;}
}

修改src/main/resources/application.properties文件

#NONE:不拦截,JWT:拦截JWT,SESSION:拦截SESSION
interceptor.mode=JWT

src/main/java/com/lala/AppForServer4.java文件内容如下

package com.lala;import com.lala.controller.LoginInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@SpringBootApplication
public class AppForServer4 implements WebMvcConfigurer {@Beanpublic LoginInterceptor loginInterceptor() {return new LoginInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {//拦截以api打头的所有请求registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/**");}@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://localhost:7070").allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE").allowCredentials(true)//是否发送cookie.allowedHeaders("*").allowedOriginPatterns("*")//意味着任何来源都可以访问该应用.allowCredentials(true);}public static void main(String[] args) {SpringApplication.run(AppForServer4.class, args);}
}

这个时候登录就会做token校验

校验token失败是因为在登录的时候发送了下面的请求

const { runAsync: menu } = useRequest<AxiosRespMenuAndRoute, string[]>((username) => _axios.get(`/api/menu/${username}`), { manual: true })

这个请求没有携带合法的token

登录的时候还发送了另一个请求

const { runAsync: login } = useRequest<AxiosRespToken, LoginDto[]>((dto) => _axios.post('/api/loginJwt', dto), { manual: true })

这个请求在白名单中,被放行了

要在登录的时候携带合法的token,可以在src\api\request.ts文件中添加请求拦截器,在拦截器中可以对请求进行统一的处理,代码如下

import { message } from "ant-design-vue";
import axios from 'axios'  
import {serverToken} from '../router/a6router'
const _axios = axios.create({baseURL: import.meta.env.VITE_BACKEND_BASE_URL,timeout: 10000,headers: {"Content-Type": "application/json",},
});
_axios.interceptors.request.use((config)=>{// 如果登录成功if(serverToken.value){config.headers = {// 因为在登录的时候把token保存在本地存储里面了,可以从这里面获取token的值Authorization: serverToken.value}}return config},(error)=>{// 这里是把异常抛给调用者return Promise.reject(error)}
)
_axios.interceptors.response.use((res) => {if(res.data.message){message.success(res.data.message)}return res;
});
export default _axios

再登陆

登录成功,可以看到admin请求携带了一个Authorization头,里面是token值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/582122.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的LVM与磁盘配额

一.LVM 1.什么是LVM Logical Volume Manager 逻辑卷管理 能够在保持现有数据不变的情况下&#xff0c;动态调整磁盘容量&#xff0c;从而提高磁盘管理的灵活性 /boot 分区用于存放引导文件&#xff0c;不能基于LVM创建 解释&#xff1a;就是将多个不同的物理卷组合在一起形…

C++设计模式代码--单例模式

参考&#xff1a;5. 单例模式&#xff08;Singleton&#xff09; (yuque.com) 1、什么是单例模式 保证一个类只有一个实例&#xff0c;并提供一个访问该实例的全局节点&#xff1b; 2、什么情况下需要单例模式 某个类的对象在软件运行之初就创建&#xff0c;并且在软件的很…

Python高级用法:迭代器(iter)

迭代器 迭代器是一个实现了迭代器协议的容器对象。它基于以下两个方法。 __ next __&#xff1a;返回容器的下一个元素。 __ iter __&#xff1a;返回迭代器本身 迭代器可以利用内置的iter函数和一个序列来创建, 假设我们的序列为[1, 2, 3],迭代器创建过程如下&#xff1a; i…

读取无标题列表txt文本文件

文件如下&#xff1a; 使用pandas直接读取&#xff0c;有多少条数据&#xff0c;就会读出来多少列&#xff1a; import pandas as pdfilepath/Users/。。。/ file1失败名单.txt df1pd.read_csv(filepathfile1,sep,,headerNone) 会打印出无数列数据&#xff1a; 使用open方法读…

3. SQL - 查询

1.SQL-单表查询 1.1 DQL准备工作 #创建商品表: create table product( pid int primary key, pname varchar(20), price double, category_id varchar(32) ); INSERT INTO product(pid,pname,price,category_id) VALUES(1,联想,5000,c001); INSERT INTO product(pid,pname,p…

31.Java程序设计-基于Springboot的鲜花商城系统的设计与实现

引言 背景介绍&#xff1a;鲜花商城系统的兴起和发展。研究目的&#xff1a;设计并实现一个基于Spring Boot的鲜花商城系统。论文结构概述。 文献综述 回顾相关鲜花商城系统的设计与实现。分析不同系统的优缺点。强调Spring Boot在系统设计中的优越性。 系统设计 需求分析 用户…

本地缓存Caffeine的使用

1 依赖 <dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.9.2</version> </dependency> 2 应用 2.1 创建缓存实例 下面是创建支持缓存自动过期的缓存实例。 /…

【头歌实训】Spark MLlib ( Python 版 )

文章目录 第1关&#xff1a;基本统计编程要求测试说明答案代码 第2关&#xff1a;回归编程要求测试说明参考资料答案代码 第3关&#xff1a;分类编程要求测试说明参考资料答案代码 第4关&#xff1a;协同过滤编程要求测试说明参考资料答案代码 第5关&#xff1a;聚类编程要求测…

优秀数据库开发工具Navicat Premium 16 Mac/win中文版

Navicat Premium 16作为一款综合性的数据库开发工具&#xff0c;可以支持主流的数据库管理系统&#xff0c;如MySQL、MariaDB、Oracle、SQL Server等。无论是进行数据库建模、数据导入导出、SQL脚本编辑&#xff0c;还是数据同步、备份恢复等操作&#xff0c;Navicat Premium 1…

反射型xss的常用语法

Xss反射型常用语法&#xff1a; 普通语法: <script>alert(1)</script>构造闭合语法&#xff1a; "><script>alert(1)</script>当引号被转义时的语法: 1 οnclickalert(2) 再次点击输入框时就会出现弹窗当3.的双引号不行时则考虑使用双引号…

【Vulnhub 靶场】【Hms?: 1】【简单】【20210728】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/hms-1,728/ 靶场下载&#xff1a;https://download.vulnhub.com/hms/niveK.ova 靶场难度&#xff1a;简单 发布日期&#xff1a;2021年07月28日 文件大小&#xff1a;2.9 GB 靶场作者&#xff1a;niveK 靶场系…

【产品经理】axure中继器的使用——表格增删改查分页实现

笔记为个人总结笔记&#xff0c;若有错误欢迎指出哟~ axure中继器的使用——表格增删改查分页实现 中继器介绍总体视图视频预览功能1.表头设计2.中继器3.添加功能实现4.删除功能实现5.修改功能实现6.查询功能实现7.批量删除 中继器介绍 在 Axure RP9 中&#xff0c;中继器&…

Visual Studio 2013 中创建一个基于 Qt 的动态链接库:并在MFC DLL程序中使用

在本地已经安装好 Qt 的情况下&#xff0c;按照以下步骤在 Visual Studio 2013 中创建一个基于 Qt 的动态链接库&#xff1a; 一、新建 Qt 项目&#xff1a; 在 Visual Studio 中&#xff0c;选择 “文件” -> “新建” -> “项目…”。在 “新建项目” 对话框中&#…

【轻松入门】OpenCV4.8 + QT5.x开发环境搭建

引言 大家好&#xff0c;今天给大家分享一下最新版本OpenCV4.8 QT5 如何一起配置&#xff0c;完成环境搭建的。 下载OpenCV4.8并解压缩 软件版本支持 CMake3.13 或者以上版本 https://cmake.org/ VS2017专业版或者以上版本 QT5.15.2 OpenCV4.8源码包 https://github.com/op…

C# 学习网站

C# 文档 - 入门、教程、参考。 | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/ Browse code samples | Microsoft LearnGet started with Microsoft developer tools and technologies. Explore our samples and discover the things you can build.http…

SpingBoot的项目实战--模拟电商【1.首页搭建】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于SpringBoot电商项目的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.项目背景及技术点运用 …

TikTok真题第6天 | 146.LRU缓存、333.最大的二分搜索树、621.任务调度器

146.LRU缓存 题目链接&#xff1a;146.lru-cache 解法&#xff1a; 这个题代码量大&#xff0c;光看题解就1个小时多了&#xff0c;看完写下来花了两小时多... 使用哈希表双向链表来实现LRU缓存的特性&#xff0c;即哈希表可以实现get为O(1)复杂度&#xff0c;双向链表可以…

Mybatis Mapper XML文件-缓存(cache)

MyBatis包含一个强大的事务查询缓存特性&#xff0c;可以进行灵活的配置和自定义。在MyBatis 3的缓存实现中进行了许多改进&#xff0c;使其更加强大且更易于配置。 默认情况下&#xff0c;仅启用了本地会话缓存&#xff0c;该缓存仅用于缓存会话期间的数据。要启用全局的第二…

C++ 一个有bug的贪吃蛇。。。。。。。。

C 一个有bug的贪吃蛇。。。。。。。。 #include <graphics.h> #include<Windows.h> #include<Mmsystem.h> #include<conio.h> #include<time.h> #include<stdio.h> #include<easyx.h> using namespace std; #pragma warning(di…

Qt之自定义分页(翻页)控件

当数据量较大时,分页显示是个不错的选择。这里用百家姓来演示分页效果,包括首页、上一页、下一页、尾页和跳转。 一.效果 每页15个姓氏。 二.实现 QHPageWidget.h #ifndef QHPAGEWIDGET_H #define QHPAGEWIDGET_H#include <QWidget> #include <QStandardItemMod…