网站常用功能模块-鉴权
一:JWT是什么?
常用鉴权方式有很多种,今天主要介绍基于token的鉴权方式JWT(Json JSON Web Token)。因为这种方式实现起来方便快捷。整体实现逻辑如下
第一次登陆时,前端携带账号和密码请求登录接口。服务端在验证登录通过后,将用户信息加密为一个token字符串返给前端。前端将token存在localstorage中。
在一般的业务请求中,前端从localstorage中取出并携带token。服务端接收到token后解密验证其时效性及合法性,如果token通过则正常返回数据,不通过则返回异常。

二:前端注意点
按照惯例前端请求接口时,携带token发送。token建议放在header中,命名为Authorization。尽量避免将token与一般入参一块放在body中,这样更加规范。
var config = {headers: {'Authorization': Token // 将 Token 放入 Authorization Header 中}};var PostData = Object.assign({}, Para['RequestData']);axios.post(Para['Url'], PostData,config).then(function (response) {})
然后在封装的异步请求方法中,直接携带token。即可完成集中处理,一劳永逸
Vue.prototype.SQAjax = function (Para) {var that = this;let AjaxLoading = Loading.service({ background: 'rgba(0,0,0,0.5)',lock: true,text: '加载中',spinner: 'el-icon-loading',fullscreen: true});var Token = localStorage.getItem('sqBlogToken') ? localStorage.getItem('sqBlogToken') : '';if (!Token) {AjaxLoading.close(); // 中断代码前,注意关闭loadingthis.$router.push({ name: 'LoginPage' });return false;}// 设置请求头var config = {headers: {'Authorization': Token // 将 Token 放入 Authorization Header 中}};var PostData = Object.assign({}, Para['RequestData']);axios.post(Para['Url'], PostData,config).then(function (response) {AjaxLoading.close();if (response.data.statusCode == 200) {Para['Success'](response.data.data);} else if (response.data.status == '1') { that.$message({message: response.data.data.message,type: 'success'});that.$router.push({name: 'LoginPage',});} else { // 返参异常的场景处理that.$message({message: response.data.data.message,type: 'error',duration: 900});}}).catch(function (error) { // 接口不通的场景处理AjaxLoading.close();that.$message({message: "接口不通",type: 'error',duration: 900});});}
三:服务端工作
1、处理token的公共类
Java中使用jjwt的原生方法,即可以轻松搞定加密解密。先注入依赖,然后创建一个JwtUtil.java,当作公共文件备用。
其中需要注意密钥的保存,如果代码开源可将密钥放在配置文件中,且保障该配置文件不开源。
// pom依赖注入
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
public class JwtUtil {private static final String SECRET_KEY = "your_secret_key";// 生成 Tokenpublic static String generateToken(User user) {return Jwts.builder().setSubject(user.getName()).claim("id", user.getId()).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hour expiration.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();}// 验证 Tokenpublic static Claims validateToken(String token) throws Exception {try {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();} catch (ExpiredJwtException e) {throw new Exception("Token 已过期", e);} catch (UnsupportedJwtException e) {throw new Exception("Token 格式不支持", e);} catch (MalformedJwtException e) {throw new Exception("Token 无效", e);} catch (SignatureException e) {throw new Exception("Token 签名无效", e);} catch (IllegalArgumentException e) {throw new Exception("Token 参数无效", e);}}
}
2、验证token
如果开发管理后台,除了登录/注册操作,其他接口基本都需要鉴权。此种场景每个controller都鉴权一次过于繁琐。可使用拦截器,做到统一处理。
如下为配置拦截器,可将登录注册等不需要token验证的接口加入白名单。
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate JwtInterceptor jwtInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor).addPathPatterns("/**") // 拦截所有请求.excludePathPatterns("/login", "/register"); // 排除登录和注册接口}
}
如下为拦截器具体代码
@Component
public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (token == null || token.isEmpty()) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("Token is missing");return false;}try {JwtUtil.validateToken(token);} catch (Exception e) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("Invalid token: " + e.getMessage());return false;}return true;}
}
3、生成token
关于需要生成token的接口,其实只有登录接口一个地方。其余接口都是验证token
可在校验登录成功后,将用户信息及token一并返回前端。
String token = jwtUtil.generateToken(userInfo);
UserAuthResponse userAuthResponse = new UserAuthResponse(token, userInfo);
return ApiResponse.success(userAuthResponse);
相关文章:
网站常用功能模块-鉴权
一:JWT是什么? 常用鉴权方式有很多种,今天主要介绍基于token的鉴权方式JWT(Json JSON Web Token)。因为这种方式实现起来方便快捷。整体实现逻辑如下 第一次登陆时,前端携带账号和密码请求登录接口。服务…...
直接插入排序、折半插入排序、2路插入排序、希尔排序
本篇是排序专栏博客的第一篇,主要探讨以 “插入” 为核心思想的排序算法该如何实现 文章目录 一、前言二、直接插入排序1. 算法思想与操作分析2. 代码实现version 1version 2 3. 复杂度分析 三、折半插入排序1. 算法思想与操作分析2. 代码实现3. 复杂度分析 四、2路…...
FQ-GAN代码解析
主要看 model 、loss 和 data 部分如何实现和处理的。 model—VQ_modelsVQModelEncoderVectorQuantizerDecoder loss—VQLoss_triple_codebook model—VQ_models 创建vq_model直接根据传入的模型压缩倍率8/16初始化对应的VQ_8/VQ_16,两者都是初始化一个VQModel的类…...
如何恢复已删除的 Telegram 消息 [iOSamp;Android]
Telegram 是一款功能强大的消息应用程序,因其易用性、隐私保护和众多炫酷功能而深受用户喜爱。然而,有时我们会不小心删除重要的消息。在这种情况下你应该做什么? 本文将为您提供简单有效的解决方案来恢复 Telegram 上已删除的消息ÿ…...
asp.net core中的 Cookie 和 Session
在 Web 开发中,用户会话管理是非常重要的,尤其是在需要保持用户状态和身份验证的应用中。ASP.NET Core 提供了多种状态管理技术,如 Cookie 和 Session,它们可以帮助你管理用户会话、存储数据并实现用户身份验证等功能。下面将详细…...
Python实现一个简单的 HTTP echo 服务器
一个用来做测试的简单的 HTTP echo 服务器。 from http.server import HTTPServer, BaseHTTPRequestHandler import jsonclass EchoHandler(BaseHTTPRequestHandler):def do_GET(self):# 构造响应数据response_data {path: self.path,method: GET,headers: dict(self.headers…...
Ruby 中文编码
Ruby 中文编码 在 Ruby 编程语言中处理中文编码是一个常见的需求,尤其是在中国和其他使用中文的地区。Ruby 是一种动态、开放源代码的编程语言,它支持多种字符编码,包括中文编码。本文将探讨在 Ruby 中处理中文编码的几种方法,以…...
淘金优化算法的信息共享与更新机制改进
淘金优化算法作为一种模拟自然界淘金过程的启发式搜索算法,在解决复杂优化问题时展现出独特优势。然而,其性能在很大程度上依赖于信息共享与更新机制的有效性。传统机制在面对高维、多模态等复杂问题时,往往存在信息交流不畅、更新滞后等问题,导致算法陷入局部最优或收敛速…...
Python中的ast.literal_eval:安全地解析字符串为Python对象
Python中的ast.literal_eval:安全地解析字符串为Python对象 什么是ast.literal_eval?为什么说它是“安全”的? 如何使用ast.literal_eval?示例1:将字符串转换为列表示例2:将字符串转换为字典示例3ÿ…...
【AI数学基础】线性代数:内积和范数
(观前提醒,这是工科AI相关的数学基础的学习笔记,不是数学专业的文章,所以没有严谨的证明和定义,数院大神请勿批评) 2. 内积和范数 2.1 内积的定义 从代数的角度来说,内积是两个向量之间的一种…...
Go语言的 的泛型(Generics)核心知识
Go语言的泛型(Generics)核心知识 引言 在编程语言的发展历程中,泛型是一项重要的特性。它使得程序员能够编写更加灵活和可重用的代码,减少了代码重复,提高了类型安全性和性能。从最初的C和Java,到现代的R…...
C++vector
1. vector 的介绍及使用 1.1vector的介绍 vector的文档介绍 1.vector是表示可变大小数组的序列容器 2.就像数组一样,vector也采用的连续存储空间来存储元素,也就是意味着可以采用下标对vector 的元素进行访问,和数组一样高效但是又不像数组…...
如何配置【Docker镜像】加速器+【Docker镜像】的使用
一、配置Docker镜像加速器 1. 安装/升级容器引擎客户端 推荐安装1.11.2以上版本的容器引擎客户端 2. 配置镜像加速器 针对容器引擎客户端版本大于1.11.2的用户 以root用户登录容器引擎所在的虚拟机 修改 "/etc/docker/daemon.json" 文件(如果没有…...
Docker--Docker Network(网络)
Docker Network(网络)是Docker容器之间和容器与外部网络之间的通信和连接的一种机制。以下是对Docker Network的详细解释: 一、Docker网络的重要性 Docker容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作…...
Vue项目中生成node_modules文件夹的两种常用方法及npm优势
在Vue项目中生成node_modules文件夹的过程非常简单,主要步骤如下: 1、使用 npm 安装依赖包; 2、使用 yarn 安装依赖包。其中,推荐使用npm安装依赖包,原因如下: 兼容性更广:npm是Node.js的默认包管理工具,具有更高的兼容性。社区支持:npm拥有更大的用户基础和社区支持,…...
如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库教程
简介 本教程将向你介绍如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库。 Apache Cassandra 是一个分布式的 NoSQL 数据库,旨在处理跨多个普通服务器的大量数据,并提供高可用性,没有单点故障。Apache Cassandra 是一个高度可扩展的分布…...
leetcode 面试经典 150 题:轮转数组
链接轮转数组题序号189题型数组解法1. 额外数组法,2. 原数组翻转法(三次翻转法)难度中等熟练度✅✅✅✅ 题目 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,…...
如何在 Mac 上轻松恢复语音备忘录
在 Mac 上丢失重要的语音备忘录可能会令人沮丧,但好消息是有多种方法可以恢复它们。无论您是意外删除它们还是由于系统故障而丢失,您都可以轻松地在 Mac 上恢复语音备忘录。 在本指南中,我们将探讨两种方法:在没有备份的情况下恢…...
C++ 基础概念: 未定义行为(Undefined Behavior)
文章目录 Intro如何正确认识 UB有多少未定义行为?对 UB 的误解 C 标准定义的几种行为1. 定义的行为 (defined behavior)2. 实现定义的行为 (implementation defined behavior)3. 未指定的行为 (unspecified behavior)4. 未定义行为 (undefined behavior)揭晓答案 C 中如何定义…...
Rad Studio 11.3 Alexandria 3236a(DELPHI 11.3)官方ISO/百度云盘 下载地址
Embarcadero很高兴地宣布RAD Studio 11 Alexandria Release 3的发布,也被称为RAD Studio 11.3,同时发布的还有Delphi 11.3和CBuilder 11.3。这个版本专注于质量和改进,建立在RAD Studio 11 Alexandria三个前版本的伟大的新功能上。 RAD Studi…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
