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
在这里插入图片描述
重新登录并点击【请求后端受保护的接口】按钮
在这里插入图片描述

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

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

相关文章

2.5万字长文吃透Tomcat面试题及参考答案

目录 什么是Tomcat? Tomcat的默认端口号是多少? 如何修改Tomcat的端口号? Tomcat有哪些主要的目录结构? Tomcat的工作原理是什么? 什么是Tomcat? 如何在Linux上安装Tomcat? 如何在Windows上安装Tomcat? 如何在Tomcat中部署一个Web应用? Tomcat支持哪些部署方…

服务器硬件基础知识:新手完全指南

在互联网技术迅速发展的今天&#xff0c;服务器在各行各业的数据处理和信息服务中扮演着至关重要的角色。无论是网站托管、数据存储&#xff0c;还是复杂的云计算应用&#xff0c;都依赖于服务器的强大功能。本文将为新手详细介绍服务器硬件的基本构成和关键性能指标&#xff0…

urllib.parse

架构概述 urllib.parse 是 Python 的 URL 解析和构造库。它提供了一系列函数&#xff0c;用于解析 URL、连接 URL、分割 URL 的各个部分、编码和解码 URL 组件等。这个库在处理网络请求和操作 URL 时非常有用。 基础功能 urlparse() - 用于解析 URL。 示例:from urllib.parse…

基于标定数据将3D LiDAR点云与相机图像对齐(含C++版本代码)

这段C代码演示了如何将Velodyne激光雷达的点云数据投影到相机图像上。该过程涉及以下主要步骤: 读取并解析来自文件的标定数据&#xff0c;包括P2矩阵、R0_rect矩阵和Tr_velo_to_cam矩阵。这些矩阵用于将激光雷达点云从Velodyne坐标系转换到相机坐标系。从二进制文件中读取Velo…

HTML做成一个端午节炫酷页面

做成端午节页面之前&#xff0c;先了解一下端午节的由来&#xff1a; 1.起源与历史&#xff1a; 端午节起源于中国&#xff0c;始于春秋战国时期&#xff0c;至今已有2000多年历史。 最初是古代百越地区&#xff08;长江中下游及以南一带&#xff09;崇拜龙图腾的部族举行图…

力扣算法题:跳跃游戏 -- 多语言实现

无意间看到&#xff0c;力扣存算法代码居然还得升级vip。。。好吧&#xff0c;我自己存吧 golang: func canJump(nums []int) bool {maxNum : 0n : len(nums)for i, _ : range nums {if i > maxNum {return false}maxNum max(maxNum, inums[i])if maxNum > n-1 {return…

生物神经网络 原理分析研读03

可能有用基础介绍 人类交互1 大脑视觉的处理过程 人类交互2 听觉处理和语言中枢 人类交互3 皮肤感觉与运动系统 人类交互4 感觉输入和运动输出 人类交互5 大脑信号编码与解码 黑箱模型的介绍 黑箱模型&#xff08;Black Box&#xff09;&#xff0c;或称经验模型&#xff0c…

找素数第二、三种方法

文章目录 第一种 &#xff1a;使用标签第二种&#xff1a;本质是方法的分装 第一种 &#xff1a;使用标签 没有使用信号量。break和continue作用范围只是最近的循环&#xff0c;无法控制外部循环。 此时使用标签 对外部循环进行操作。 package com.zhang; /* 找素数 第二种方…

MySQL—多表查询—外连接

一、引言 学到内连接&#xff0c;它是查询的数据两张表交集的部分。而接下来看看外连接。 外连接查询语法&#xff1a;&#xff08;分为两种&#xff09; 1、左外连接 语法结构&#xff1a; 表1 LEFT [OUTER] JOIN 表2 ON 条件 ...; ( ... left out join on ...) 注意&#x…

56.StampedLock

jdk8加入的,为了进一步优化读性能。比ReentrantReadWriteLock性能好。但是却无法完全替代。 特点:在使用读锁、写锁时都必须配合戳使用。 优化的点在于乐观读,乐观读没有加任何的锁。 乐观读,StampedLock支持tryOptimisticRead()方法(乐观读),读取完毕后需要做一次戳…

三、安全工程练习题(CISSP)

1.三、安全工程练习题(CISSP)

WordPress 高级缓存插件 W3 Total Cache Pro 详细配置教程

说起来有关 WordPress 缓存插件明月已经发表过不少文章了,但有关 W3 Total Cache Pro 这个 WordPress 高级缓存插件除了早期【网站缓存插件 W3 Total Cache,适合自己的才是最好的!】一文后就很少再提及了,最近因为明月另一个网站【玉满斋】因为某些性能上的需要准备更换缓存…

java —— 线程(一)

一、进程与线程 一个进程可以包含一个以上的线程&#xff0c;CPU 时间片切换的基本单位是线程。 二、创建线程 &#xff08;一&#xff09;继承 Thread 类 public class Task extends Thread{Override //重写run方法public void run(){System.out.pr…

心灵清闲

人本质上是喜欢清闲的生活的。所谓“清闲”&#xff0c;就是在为稻梁奔波的同时&#xff0c;还有一些可以用来喝酒、聊天、旅游的时间。 细细想来&#xff0c;一个人要活的惬意&#xff0c;光有生理上的清闲是不够的&#xff0c;还得有心灵的清闲。只是一个人要抵达生理上的清…

当前 Python 版本中所有保留字keyword.kwlist

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 当前 Python 版本中 所有保留字 keyword.kwlist [太阳]选择题 根据给定的Python代码&#xff0c;哪个选项是正确的&#xff1f; import keyword print("【执行】keyword.kwlist"…

【数据结构】KMP算法

1 KMP算法 KMP&#xff08;Knuth-Morris-Pratt&#xff09;算法是一种改进的字符串匹配算法&#xff0c;由D.E.Knuth、J.H.Morris和V.R.Pratt共同提出&#xff0c;用于在一个文本串&#xff08;主串&#xff09;中搜索一个词&#xff08;模式串&#xff09;的位置。KMP算法的关…

shell编程(四)—— 运算符

和其他编程语言一样&#xff0c;bash也有多种类型的运算符&#xff0c;本篇对bash的相关运算符做简单介绍。 一、运算符 1.1 算术运算符 常见的算术运算符&#xff0c;如加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xf…

如何提高逻辑性?(小妙招)

在现代社会中&#xff0c;逻辑性是一种至关重要的思维能力。不论是在工作、学习还是生活中&#xff0c;逻辑清晰的人总能更好地解决问题和做出决策。然而&#xff0c;如何提高逻辑性却是许多人头疼的问题。本文将从六个方面详细探讨如何提升逻辑性&#xff0c;包括细心态度、逼…

【网络架构】Nginx

目录 一、I/O模型 1.1 Linux 的 I/O 1.2 零拷贝技术 1.3 网络IO模型 1.3.1 阻塞型 I/O 模型&#xff08;blocking IO&#xff09;​编辑 1.3.2非阻塞型 I/O 模型 (nonblocking IO)​编辑 1.3.3 多路复用 I/O 型 ( I/O multiplexing )​编辑 1.3.4 信号驱动式 I/O 模型 …

leetcode:67二进制求和

题目链接&#xff1a;67. 二进制求和 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:string addBinary(string a, string b) {int stralen a.size(), strblen b.size();int curtc;int Maxlen max(stralen, strblen);vector<int> stra;vector<i…