当前位置: 首页 > news >正文

springboot+vue前后端分离项目中使用jwt实现登录认证

文章目录

  • 一、后端代码
    • 1.响应工具类
    • 2.jwt工具类
    • 3.登录用户实体类
    • 4.登录接口
    • 5.测试接口
    • 6.过滤器
    • 7.启动类
  • 二、前端代码
    • 1.登录页
    • index 页面
  • 三、效果展示


一、后端代码

1.响应工具类

package com.etime.util;import com.etime.vo.ResponseModel;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** @Date 2024/6/10 10:00* @Author liukang**/
public class ResponseUtil {public static void write(ResponseModel rm, HttpServletResponse response) throws IOException {// 构造响应头response.setContentType(MediaType.APPLICATION_JSON_VALUE);response.setCharacterEncoding("utf-8");// 解决跨域问题 设置跨域头response.setHeader("Access-Control-Allow-Origin","*");// 输出流PrintWriter out = response.getWriter();// 输出out.write(new ObjectMapper().writeValueAsString(rm));// 关闭流out.close();}
}

2.jwt工具类

package com.etime.util;import io.jsonwebtoken.*;import java.util.Date;
import java.util.Map;
import java.util.UUID;/*** @Date 2024/6/10 10:04* @Author liukang**/
public class JwtUtil {private static String secret = "secret";/*** 创建jwt* @author liukang* @date 10:36 2024/6/10* @param expire* @param map* @return java.lang.String**/public static String generateToken(long expire, Map map){// 床jwt构造器JwtBuilder jwtBuilder = Jwts.builder();// 生成jwt字符串String jwt = jwtBuilder//头部.setHeaderParam("typ","JWT").setHeaderParam("alg","HS256")// 载荷.setClaims(map) // 设置多个自定义数据  位置只能放在前面,如果放在后面,那前面的载荷会失效.setId(UUID.randomUUID().toString())// 唯一标识.setIssuer("liukang")// 签发人.setIssuedAt(new Date())// 签发时间.setSubject("jwtDemo")// 主题.setExpiration(new Date(System.currentTimeMillis()+expire))//过期时间// 签名.signWith(SignatureAlgorithm.HS256,secret).compact();return jwt;}/*** 创建jwt* @author liukang* @date 10:36 2024/6/10* @param expire* @return java.lang.String**/public static String generateToken(long expire){// 床jwt构造器JwtBuilder jwtBuilder = Jwts.builder();// 生成jwt字符串String jwt = jwtBuilder//头部.setHeaderParam("typ","JWT").setHeaderParam("alg","HS256")// 载荷.setId(UUID.randomUUID().toString())// 唯一标识.setIssuer("liukang")// 签发人.setIssuedAt(new Date())// 签发时间.setSubject("jwtDemo")// 主题.setExpiration(new Date(System.currentTimeMillis()+expire))//过期时间// 签名.signWith(SignatureAlgorithm.HS256,secret).compact();return jwt;}/*** 解析jwt* @author liukang* @date 10:36 2024/6/10* @param jwt* @return io.jsonwebtoken.Claims**/public static Claims parseToken(String jwt){Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt);Claims playload = claimsJws.getBody();return playload;}
}

3.登录用户实体类

package com.etime.entity;import lombok.Data;/*** @Date 2024/6/10 10:39* @Author liukang**/
@Data
public class User {private String username;private String password;
}

4.登录接口

package com.etime.controller;import com.etime.entity.User;
import com.etime.util.JwtUtil;
import com.etime.vo.ResponseModel;
import org.springframework.web.bind.annotation.*;/*** @Date 2024/6/10 10:38* @Author liukang**/
@RestController
@CrossOrigin
public class LoginController {@PostMapping("/login")public ResponseModel login(@RequestBody User user){Integer code = 200;String msg = "success";String token = null;if(user.getUsername().equals("admin")&&user.getPassword().equals("123")){// 生成jwttoken = JwtUtil.generateToken(1000*10);// 设置有效期为10s}else {code = 500;msg = "failure";}return new ResponseModel(code,msg,token);}}

5.测试接口

package com.etime.controller;import com.etime.vo.ResponseModel;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;/*** @Date 2024/6/10 12:51* @Author liukang**/
@CrossOrigin
@RestController
public class TestController {@PostMapping("/test")public ResponseModel test() {return new ResponseModel(200,"success","测试请求接口成功!");}}

6.过滤器

package com.etime.filter;import com.etime.util.JwtUtil;
import com.etime.util.ResponseUtil;
import com.etime.vo.ResponseModel;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @Description jwt过滤器* @Date 2024/6/10 9:46* @Author liukang**/
@WebFilter(urlPatterns = "/*") // 过滤所有路径
public class JwtFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 得到两个对象HttpServletRequest request =  (HttpServletRequest) servletRequest;HttpServletResponse response =  (HttpServletResponse) servletResponse;//直接放行if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){filterChain.doFilter(request,response);return;}String requestURI = request.getRequestURI(); // 不含主机和端口号if(requestURI.contains("/login")){filterChain.doFilter(request,response);return;}// 得到请求头的信息(accessToken)String token = request.getHeader("accessToken");if(!StringUtils.hasText(token)){//响应前端错误的消息提示ResponseModel responseModel = new ResponseModel(500,"failure","令牌缺失!");ResponseUtil.write(responseModel,response);return;}// 解析Token信息try {JwtUtil.parseToken(token);}catch (Exception e){//响应前端错误的消息提示ResponseModel responseModel = new ResponseModel(401,"failure","令牌过期!");ResponseUtil.write(responseModel,response);return;}filterChain.doFilter(request,response);}
}

7.启动类

package com.etime;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;/*** @Author liukang* @Date 2022/7/4 11:32*/
@SpringBootApplication
@ServletComponentScan(basePackages = "com.etime.filter")// 这个包下激活WebFilter这个注解
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class);}
}

二、前端代码

1.登录页

<template><div class="hello"><form>用户名:<input v-model="username"/><br>密码<input v-model="password" /><br><button @click="login">登录</button></form></div></template><script>export default {data () {return {username:'',password:'',}},methods:{login(){this.axios.post('http://localhost:8088/login',{username:this.username,password:this.password,}).then(response => {console.log(response.data);if(response.data.code==200){sessionStorage.setItem("accessToken",response.data.token)this.$router.push({ path: 'index'});}}).catch(error => {console.error(error);});}},}</script><style scoped></style>

index 页面

<template><div><button @click="test">请求受保护的接口</button></div></template><script>export default {data () {return {}},methods:{test(){const accessToken = sessionStorage.getItem('accessToken')let token = nullif(accessToken){token = accessToken}console.log(token)this.axios.post('http://localhost:8088/test',{},{headers:{accessToken:token}}).then(response => {// if(response.data.code==200){console.log(response.data);// }}).catch(error => {console.error(error);});},},}</script><style scoped></style>

三、效果展示

1.点击登录后,后端给前端办法jwt令牌,前端将其存入sessionStorage中
在这里插入图片描述
2.点击【请求后端受保护的接口】按钮
在这里插入图片描述
3.继续多次点击【请求后端受保护的接口】按钮
在这里插入图片描述
可以看见,请求几次成功后,便显示令牌过期,这是因为,为了测试方便,我们颁发令牌时有效期设置的10秒
在这里插入图片描述
4.在请求接口中不传递Token
在这里插入图片描述
重新登录并点击【请求后端受保护的接口】按钮
在这里插入图片描述

相关文章:

springboot+vue前后端分离项目中使用jwt实现登录认证

文章目录 一、后端代码1.响应工具类2.jwt工具类3.登录用户实体类4.登录接口5.测试接口6.过滤器7.启动类 二、前端代码1.登录页index 页面 三、效果展示 一、后端代码 1.响应工具类 package com.etime.util;import com.etime.vo.ResponseModel; import com.fasterxml.jackson.…...

leetcode hot100 之 编辑距离

给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 输入&#xff1a;word1 “horse”, word2 “ros” 输出&#xff1a;3 解释&#xff1a…...

杨校老师项目之基于SpringBoot的理发店的预约管理系统

原系统是SSMJSP页面构成&#xff0c;先被修改为SpringBoot JSP页面 自助下载渠道: https://download.csdn.net/download/kese7952/89417001&#xff0c;或 点我下载 理发师信息&#xff1a; 理发师详细信息 公告信息 员工登录&#xff1a; 管理员登录...

SpringAI学习及搭建AI原生应用

文章目录 一、SpringAI是什么二、准备工作1.GPT-API-free2.AiCore3.eylink 三、对话案例实现1.创建项目2.实现简单的对话 四、聊天客户端ChatClient1.角色预设2.流式响应3.call和stream的区别 五、聊天模型提示词提示词模板 六、图像模型(文生图)七、语音模型1.文字转语音(文生…...

CobaltStrike权限传递MSF

一、测试环境 操作系统&#xff1a; 1.VMware17 2.kali 6.1.0-kali5-amd64 3.Win10x64 软件&#xff1a; 1.cs4.0 2.metasploit v6.3.4-dev 二、测试思路 1.cs是一款渗透测试工具&#xff0c;但没有漏洞利用的模块&#xff0c;我们可以在拿到目标主机的权限后&#xff0c;将…...

白嫖 kimi 接口 api

说明:kimi当然是免费使用的人工智能AI,但是要调用api是收费的. 项目&#xff1a; https://github.com/LLM-Red-Team/kimi-free-api 原文地址: https://blog.taoshuge.eu.org/p/272/ railway部署 步骤: 打开Github,新建仓库新建名为Dockerfile文件&#xff08;没有后缀&…...

借助ChatGPT完成课题申报书中框架思路写作指南

大家好&#xff0c;感谢关注。我是七哥&#xff0c;一个在高校里不务正业&#xff0c;折腾学术科研AI实操的学术人。可以和我&#xff08;yida985&#xff09;交流学术写作或ChatGPT等AI领域相关问题&#xff0c;多多交流&#xff0c;相互成就&#xff0c;共同进步 在课题申报…...

SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)

https://www.cnblogs.com/yxcblogs/p/18239433 题解写到博客园了&#xff0c;懒得复制了&#xff0c;直接放个链接吧~...

重温共射放大电路

1、放大概念 小功率信号变成一个大功率信号&#xff0c;需要一个核心器件做这件事&#xff0c;核心器件的能量由电源提供&#xff0c;通过核心器件用小功率的信号去控制大电源&#xff0c;来实现能量的转换和控制&#xff0c;前提是不能失真&#xff0c;可以用一系列正弦波进行…...

[DDR5 Jedec] 读操作 Read Command 精讲

依公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《深入理解DDR》 Read 读取命令也可以视为列读取命令。当与正确的bank地址和列地址结合使用时&#xff0c;通过激活命令&#xff08;行访问&#xff09;移动到检测放大器中的数据&#xff0c; 现在被推送到数…...

opencv 通过滑动条调整阈值处理、边缘检测、轮廓检测、模糊、色调调整和对比度增强参数 并实时预览效果

使用PySimpleGUI库创建了一个图形用户界面(GUI),用于实时处理来自OpenCV摄像头的图像。它允许用户应用不同的图像处理效果,如阈值处理、边缘检测、轮廓检测、模糊、色调调整和对比度增强。用户可以通过滑动条调整相关参数。 完整代码在文章最后,可以运行已经测试; 代码的…...

防火墙安全管理

大多数企业通过互联网传输关键数据&#xff0c;因此部署适当的网络安全措施是必要的&#xff0c;拥有足够的网络安全措施可以为网络基础设施提供大量的保护&#xff0c;防止黑客、恶意用户、病毒攻击和数据盗窃。 网络安全结合了多层保护来限制恶意用户&#xff0c;并仅允许授…...

MyQueue(队列)

目录 一、队列的定义 二、队列方法的实现 1、定义队列 2、后端插入 3、前端操作 4、判断队列是否为空 5、队列大小 三、队列方法的使用 一、队列的定义 队列是一种特殊的线性表&#xff0c;特殊之处在于它只允许在表的前端&#xff08;front&#xff09;进行删除操作&am…...

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法

【Pytorch】一文向您详细介绍 torch.nn.DataParallel() 的作用和用法 下滑查看解决方法 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高…...

Windows本地使用SSH连接VM虚拟机

WIN10 VM17.5 Ubuntu:20.04 1.网路设置 1)选择编辑->更改设置 配置完成 2.修改了服务器文件&#xff0c;修改sshd配置&#xff0c;在此文件下/etc/ssh/sshd_config&#xff0c;以下为比较重要的配置 PasswordAuthentication yes PermitRootLogin yes PubkeyAuthenticat…...

RPC(远程过程调用):技术原理、应用场景与发展趋势

摘要&#xff1a; RPC&#xff08;Remote Procedure Call&#xff09;是一种通信协议&#xff0c;用于实现跨网络的进程间通信。它提供了一种简单高效的方式&#xff0c;使得分布式系统中的不同组件能够像调用本地函数一样调用远程函数。本篇博客将介绍RPC的基本概念&#xff0…...

iSCSI和FC存储

iSCSI存储和FC存储的特点和区别 FC存储和iSCSI存储是两种主要的网络存储解决方案&#xff0c;它们各自在性能、成本和适用场景上有着不同的特点。 FC存储是一种基于光纤通道技术的高性能、低延迟的存储解决方案。它使用专用的光纤通道网络连接存储设备和服务器&#xff0c;确…...

MPT(merkle Patricia trie )及理解solidity里的storage

what&#xff1f; MPT树是一种数据结构&#xff0c;用于在以太坊区块链中高效地存储和检索账户状态、交易历史和其他重要数据。MPT树的设计旨在结合Merkle树和Patricia树的优点&#xff0c;以提供高效的数据存储和验证 MPT树由四种类型的节点组成&#xff1a; **扩展节点&…...

【代码随想录算法训练营第三十五天】 | 1005.K次取反后最大化的数组和 134.加油站 135.分发糖果

贪心章节的题目&#xff0c;做不出来看题解的时候&#xff0c;千万别有 “为什么这都没想到” 的感觉&#xff0c;想不出来是正常的&#xff0c;转变心态 “妙啊&#xff0c;又学到了新的思路” &#xff0c;这样能避免消极的心态对做题效率的影响。 134. 加油站 按卡哥的思路…...

桌面应用开发框架比较:Electron、Flutter、Tauri、React Native 与 Qt

在当今快速发展的技术环境中&#xff0c;对跨平台桌面应用程序的需求正在不断激增。 开发人员面临着选择正确框架之挑战&#xff0c;以便可以高效构建可在 Windows、macOS 和 Linux 上无缝运行的应用程序。 在本文中&#xff0c;我们将比较五种流行的桌面应用程序开发框架&…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...