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.rhkb.cn/news/230739.html

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

相关文章

PE解释器之PE文件结构

PE文件是由许许多多的结构体组成的&#xff0c;程序在运行时就会通过这些结构快速定位到PE文件的各种资源&#xff0c;其结构大致如图所示&#xff0c;从上到下依次是Dos头、Nt头、节表、节区和调试信息(可选)。其中Dos头、Nt头和节表在本文中统称为PE文件头(因为SizeOfHeaders…

virtualbox新建Ubuntu虚拟机

1、下载virtualbox 2、下载Ubuntu镜像 https://ubuntu.com/blog/desktop virtualbox安装好后&#xff0c;点击新建 选择linux类型 选择内存2~4G都行 选择先不添加虚拟硬盘 创建硬盘&#xff0c;管理点击虚拟介质管理 点击创建&#xff0c;选择创建类型为vmdk&#xff0…

Linux 进程(八) 进程的退出码

main 函数的返回值叫做进程的退出码。当进程成功退出的时候&#xff0c;我们一般用0来表示。进程失败的时候一般用非零来表示。我们使用不同的数字来表示进程退出时不同的失败原因。 我们查看系统的有多少退出码以及其含义时需要用到strerror() 他的头文件和用法如下。 通过一…

输入输出流

1.输入输出流 输入/输出流类&#xff1a;iostream---------i input&#xff08;输入&#xff09; o output&#xff08;输出&#xff09; stream&#xff1a;流 iostream&#xff1a; istream类&#xff1a;输入流类-------------cin&#xff1a;输入流类的对象 ostream类…

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(2)

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜&#xff0c;Kotlin&#xff08;2&#xff09; 在 Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜&#xff0c;Kotlin&#xff08;1&#xff09; Android Matrix剪切clipPath缩放scale图片po…

Apache Doris (六十): Doris - 物化视图

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录

大文件快速传输解决办法汇总

在数据传输普及的当今时代&#xff0c;文件体量也在不断的突破它”大“的上线&#xff0c;很多企业也在面临着这类大文件快速传输的烦恼&#xff0c;而且这里面的“大”可不是一般意义的几M,几G的文件&#xff0c;它有可能上T级甚至是PB级别、TB级别的大文件&#xff0c;或者是…

CCNP课程实验-07-OSPF-Trouble-Shooting

目录 实验条件网络拓朴 环境配置开始排错错点1&#xff1a;R1-R2之间认证不匹配错误2&#xff1a;hello包的时间配置不匹配错误3&#xff1a;R2的e0/1接口区域配置不正确错误4&#xff1a;R4的e0/1接口没有配置进OSPF错误5&#xff1a;R2的区域1没有配置成特殊区域错误6&#x…

文件摆渡系统如何实现网络隔离后的数据交换、业务流转?

近年来全球网络安全威胁态势的加速严峻&#xff0c;使得企业对于网络安全有了前所未有的关注高度。即便没有行业性的强制要求&#xff0c;但在严峻的安全态势之下&#xff0c;企业的网络安全体系建设正从“以合规为导向”转变到“以风险为导向”&#xff0c;从原来的“保护安全…

SpringCloud微服务安全之API审计日志功能实现

SpringCloud微服务安全之API审计日志功能实现 1.审计功能介绍2.记录的实体类设计3.保存审计记录到数据库的工具4.审计功能实现1.审计功能介绍 审计日志 定义:谁,在什么时间,干了什么事。位置:认证之后,授权之前。这样就知道是谁在访问,拒绝掉的访问也能被记录。如果放在认…

分享10篇优秀论文,涉及图神经网络、大模型优化、表格分析

引言 第38届AAAI人工智能年度会议将于2024年2月在加拿大温哥华举行。今天给大家分享十篇AAAI2024论文&#xff0c;主要涉及图神经网络&#xff0c;大模型幻觉、中文书法文字生成、表格数据分析、KGs错误检测、多模态Prompt、思维图生成等。 论文获取方式&#xff0c;回复&am…

微服务实战系列之Dubbo(下)

前言 眼看着2023即将走远&#xff0c;心里想着似乎还有啥&#xff0c;需要再跟各位盆友叨叨。这不说曹操&#xff0c;曹操就来了。趁着上一篇Dubbo博文的余温尚在&#xff0c;博主兴匆匆地“赶制”了Dubbo的下集&#xff0c;以飨读者。 上一篇博主依然从Dubbo的内核出发&#…

C++第四天

定义一个Person类&#xff0c;私有成员int age&#xff0c;string &name&#xff0c;定义一个Stu类&#xff0c;包含私有成员double *score&#xff0c;写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数&#xff0c;完成对Person的运算符重载(算术运算符、条件运算…

Winform中使用Fleck实现Websocket服务端并读取SQLite数据库中数据定时循环群发消息

场景 Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中&#xff1a; Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中-CSDN博客 Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作&#xff1a; Wi…

docker 安装可视化工具 Portainer 以及 汉化

安装portainer是最新版本&#xff0c;汉化指定版本2.9.1 。如果要安装汉化版&#xff0c;可直接跳转步骤四 一、拉去镜像 安装网址&#xff1a;Install Portainer BE with Docker on Linux - Portainer Documentation docker pull portainer/portainer二、根据portainer镜像创建…

利用 PEB_LDR_DATA 结构枚举进程模块信息

1. 引言 我们常常通过很多方法来获取进程的模块信息&#xff0c;例如 EnumProcessModules 函数、CreateToolhelp32Snapshot 函数、WTSEnumerateProcesses 函数、ZwQuerySystemInformation 函数等。但是调用这些接口进行模块枚举的原理是什么我们并不知道。通过学习 PEB 中 PEB…

Prometheus-AlertManager 邮件告警

环境,软件准备 本次演示环境&#xff0c;我是在虚拟机上安装 Linux 系统来执行操作&#xff0c;以下是安装的软件及版本&#xff1a; System: CentOS Linux release 7.6Docker: 24.0.5Prometheus: v2.37.6Consul: 1.6.1 docker 安装prometheus,alertmanage,说明一下这里直接将…

ArrayList学生管理系统

文章目录 1.ArrayList集合和数组的优势对比&#xff1a;1.1 ArrayList类概述1.2 ArrayList类常用方法1.2.1 构造方法1.2.2 成员方法1.2.3 示例代码 1.3 ArrayList存储字符串并遍历1.3.1 案例需求1.3.2 代码实现 1.4 ArrayList存储学生对象并遍历1.4.1 案例需求1.4.2 代码实现 1…

【LLM】大型语言模型综述论文

今天我将与大家分享一篇精彩的论文。这项调查提供了LLM文献的最新综述&#xff0c;这对研究人员和工程师来说都是一个有用的资源。 为什么选择LLM&#xff1f; 当参数尺度超过一定水平时&#xff0c;这些扩展的语言模型不仅实现了显著的性能改进&#xff0c;而且还表现出一些…

uniCloud 云数据库(新建表、增、删、改、查)

新建表结构描述文件 todo 为自定义的表名 表结构描述文件的默认后缀为 .schema.json 设置表的操作权限 uniCloud-aliyun/database/todo.schema.json 默认的操作权限都是 false "permission": {"read": false,"create": false,"update&quo…