Spring Boot+Vue前后端分离项目练习02之网盘项目利用token进行登陆验证
1.添加依赖
首先需要添加jwt对应的依赖。
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
2.添加配置
JWT由三部分构成,分别是 header, payload 和 signature, 其中前两部分中的参数涉及到的一些参数需要用户自定义,因此我们需要将这些参数放到配置文件中,这样后续就可以动态修改配置。
# 密钥
jwt.secret = 6L6T5LqG5L2g77yM6LWi5LqG5LiW55WM5Y+I6IO95aaC5L2V44CC
# 签名算法:HS256,HS384,HS512,RS256,RS384,RS512,ES256,ES384,ES512,PS256,PS384,PS512
jwt.header.alg = HS256
#jwt签发者
jwt.payload.iss = picacho
#jwt过期时间(单位:毫秒)
jwt.payload.exp = 60 * 60 * 1000 * 24 * 7
#jwt接收者
jwt.payload.aud = picacho_1
3.创建JWT配置类
创建config包,在该包下创建JWT对应的配置类。
import lombok.Data;@Data
public class JwtHeader {private String alg;private String typ;
}
import lombok.Data;@Data
public class JwtPayload {private String iss;private String exp;private String sub;private String aud;
}
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {private String secret;private JwtHeader header;private JwtPayload payload;
}
这里通过配置文件的属性值来为jwt进行属性值的配置。
4.创建JWT工具类
创建JWTUtil类,在里面创建generalSecretKey方法来生成密钥,生成的过程需要使用 JWT的方法SecretKeySpec来生成密钥,该密钥在创建JWT和验证 JWT 的时候都会用到且相同。
@Component
public class JWTUtil {@ResourceJwtProperties jwtProperties;/*** 由字符串生成加密key* @return*/private SecretKey generalKey() {// 本地的密码解码byte[] encodedKey = Base64.decodeBase64(jwtProperties.getSecret());// 根据给定的字节数组使用AES加密算法构造一个密钥SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}
}
创建生成JWT方法。
/*** 创建jwt* @param subject* @return* @throws Exception*/public String createJWT(String subject) throws Exception {// 生成JWT的时间long nowTime = System.currentTimeMillis();Date nowDate = new Date(nowTime);// 生成签名的时候使用的秘钥secretSecretKey key = generalKey();ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine se = manager.getEngineByName("js");int expireTime = 0;try {expireTime =(int) se.eval(jwtProperties.getPayload().getExp());} catch (ScriptException e) {e.printStackTrace();}// 为payload添加各种标准声明和私有声明DefaultClaims defaultClaims = new DefaultClaims();defaultClaims.setIssuer(jwtProperties.getPayload().getIss());defaultClaims.setExpiration(new Date(System.currentTimeMillis() + expireTime));defaultClaims.setSubject(subject);defaultClaims.setAudience(jwtProperties.getPayload().getAud());JwtBuilder builder = Jwts.builder() // 表示new一个JwtBuilder,设置jwt的body.setClaims(defaultClaims).setIssuedAt(nowDate) // iat(issuedAt):jwt的签发时间.signWith(SignatureAlgorithm.forName(jwtProperties.getHeader().getAlg()), key); // 设置签名,使用的是签名算法和签名使用的秘钥return builder.compact();}
创建解密JWT方法。
/*** 解密jwt* @param jwt* @return* @throws Exception*/public Claims parseJWT(String jwt) throws Exception {SecretKey key = generalKey(); // 签名秘钥,和生成的签名的秘钥一模一样Claims claims = Jwts.parser() // 得到DefaultJwtParser.setSigningKey(key) // 设置签名的秘钥.parseClaimsJws(jwt).getBody(); // 设置需要解析的jwtreturn claims;}
5.实现用户注册
5.1 实现业务层
创建service包,在该包下创建UserService.java类,实现用户注册逻辑。
import com.picacho.common.RestResult;
import com.picacho.entity.User;public interface UserService {RestResult<String> registerUser(User user);
}
创建impl包,在该包下创建其实现类。
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@ResourceUserMapper userMapper;@Overridepublic RestResult<String> registerUser(User user) {//判断验证码String telephone = user.getTelephone();String password = user.getPassword();if (!StringUtils.hasLength(telephone) || !StringUtils.hasLength(password)){return RestResult.fail().message("手机号或密码不能为空!");}if (isTelePhoneExit(telephone)){return RestResult.fail().message("手机号已存在!");}String salt = UUID.randomUUID().toString().replace("-", "").substring(15);String passwordAndSalt = password + salt;String newPassword = DigestUtils.md5DigestAsHex(passwordAndSalt.getBytes());user.setSalt(salt);user.setPassword(newPassword);user.setRegisterTime(DateUtil.getCurrentTime());int result = userMapper.insert(user);if (result == 1) {return RestResult.success();} else {return RestResult.fail().message("注册用户失败,请检查输入信息!");}}/*** 判断手机号是否存在* @param telePhone* @return*/private boolean isTelePhoneExit(String telePhone) {LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(User::getTelephone, telePhone);List<User> list = userMapper.selectList(lambdaQueryWrapper);if (list != null && !list.isEmpty()) {return true;} else {return false;}}
}
5.2 创建DTO类
在前后端分离项目中,一般前端与后端需要统一数据交互;一般做法是创建DTO类,例如注册功能,这里可以创建RegisterDTO.java,其属性就是前端需要传给后端的数据。
创建dto包,在该包下创建RegisterDTO.java。
import lombok.Data;@Data
public class RegisterDTO {private String username;private String telephone;private String password;
}
5.3 添加注册接口
@ResourceUserService userService;@PostMapping(value = "/register")@ResponseBodypublic RestResult<String> register(@RequestBody RegisterDTO registerDTO) {RestResult<String> restResult = null;User user = new User();user.setUsername(registerDTO.getUsername());user.setTelephone(registerDTO.getTelephone());user.setPassword(registerDTO.getPassword());restResult = userService.registerUser(user);return restResult;}
5.4 测试效果
启动项目测试效果:
6.实现用户登陆
6.1 实现业务层
RestResult<User> login(User user);
@Overridepublic RestResult<User> login(User user) {String telephone = user.getTelephone();String password = user.getPassword();LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(User::getTelephone, telephone);User saveUser = userMapper.selectOne(lambdaQueryWrapper);String salt = saveUser.getSalt();String passwordAndSalt = password + salt;String newPassword = DigestUtils.md5DigestAsHex(passwordAndSalt.getBytes());if (newPassword.equals(saveUser.getPassword())) {saveUser.setPassword("");saveUser.setSalt("");return RestResult.success().data(saveUser);} else {return RestResult.fail().message("手机号或密码错误!");}}
6.2 创建VO类
import lombok.Data;@Data
public class LoginVO {private String username;private String token;
}
6.3 添加登陆接口
@ResourceJWTUtil jwtUtil;@GetMapping(value = "/login")@ResponseBodypublic RestResult<LoginVO> userLogin(String telephone, String password) {RestResult<LoginVO> restResult = new RestResult<LoginVO>();LoginVO loginVO = new LoginVO();User user = new User();user.setTelephone(telephone);user.setPassword(password);RestResult<User> loginResult = userService.login(user);if (!loginResult.getSuccess()) {return RestResult.fail().message("登录失败!");}loginVO.setUsername(loginResult.getData().getUsername());String jwt = "";try {ObjectMapper objectMapper = new ObjectMapper();jwt = jwtUtil.createJWT(objectMapper.writeValueAsString(loginResult.getData()));} catch (Exception e) {return RestResult.fail().message("登录失败!");}loginVO.setToken(jwt);return RestResult.success().data(loginVO);}
6.4 测试效果
启动项目测试效果:
这里返回了token,后面就可以通过携带token来访问需要登陆才能有权限访问的路径。
7.验证token
@GetMapping("/checkToken")@ResponseBodypublic RestResult<User> checkToken(@RequestHeader("token") String token) {RestResult<User> restResult = new RestResult<User>();User tokenUserInfo = null;try {Claims c = jwtUtil.parseJWT(token);String subject = c.getSubject();ObjectMapper objectMapper = new ObjectMapper();tokenUserInfo = objectMapper.readValue(subject, User.class);} catch (Exception e) {return RestResult.fail().message("认证失败");}if (tokenUserInfo != null) {return RestResult.success().data(tokenUserInfo);} else {return RestResult.fail().message("用户暂未登录");}}
7.1 测试效果
启动项目,携带token测试效果。
可以看到验证成功了。
项目demo源码下载地址:源码下载
相关文章:
Spring Boot+Vue前后端分离项目练习02之网盘项目利用token进行登陆验证
1.添加依赖 首先需要添加jwt对应的依赖。 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>2.添加配置 JWT由三部分构成,分别是 header, pa…...
springcloud常见面试题(2023最新)
目录前言一.微服务1.微服务是什么?2.你知道哪些RPC框架3.springCloud和Dubbo有什么区别4. SpringCloud由什么组成二.Spring Cloud Eureka1.Eureka包含几个组件2.Eureka的工作原理3.说一下什么是Eureka的自我保护机制4.什么是CAP原则5.都是服务注册中心,E…...
用户态驱动的两种方式-ixy学习
介绍在Linux下有两种启用用户态驱动的子系统:一个是UIO,另一个是VFIO,ixy这两种都支持。 UIO通过虚拟文件系统sysfs下的内存映射文件来暴露所有必要的接口以完成用户态的驱动。这些基于文件的系统调用接口给了我们充足的权限来获取设备资源而…...
机器学习 | 线性回归(单变量)
前文回顾:机器学习概述📚线性回归概念我们要使用一个数据集,数据集包含俄勒冈州波特兰市的住房价格。在这里,我要根据不同房屋尺寸所售出的价格,画出我的数据集。比方说,如果你朋友的房子是 1250 平方尺大小…...
C++基础知识【3】控制语句
目录 前言 一、条件语句 1.1、if 语句 1.2、if-else 语句 1.3、switch 语句 二、循环语句 2.1、while 循环 2.2、do-while 循环 2.3、for 循环 三、跳转语句 3.1、break语句 3.2、continue语句 3.3、goto语句 四、一些新特性 4.1、if 语句和 switch 语句…...
ImportError: Can not find the shared library: libhdfs3.so解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...
Qt插件开发总结5--主界面嵌入插件UI
文章目录一、前言二、效果展示三、嵌入插件UI1、插件接口文件添加UI指针2、插件子项目工程建立UI类3、插件类中创建UI类、使UI指针指向创建的UI类4、插件元信息中添加widget键值对,指示插件UI嵌入主界面中的位置5、主界面中预留接入点tabWidget6、插件管理器中元数据…...
一些关于linux process 和python process的记录
python mulprocess 主要用来生成另一个进程并运行 def func(i):print(helloworld)from multiprocessing import Process p Process(targetfunc,args(i, )) p.start()如果想要调用shell命令,可以采用os.popen 或者是 subprocess.run 但是前者只能执行命令并获取输…...
卡尔曼滤波——一种基于滤波的时序状态估计方法
文章目录1. Kalman滤波及其应用2. Kalman原理公式推导:Step 1:模型建立Step 2:开始Kalman滤波Step 3:迭代滤波本文是对 How a Kalman filter works, in pictures一文学习笔记,主要是提炼核心知识,方便作者快…...
什么是X6CrMo17-1
X6CrMo17-1X6CrMo17-1是在430的基礎上加入了鉬,提高鋼的耐點蝕、耐縫隙腐蝕性及強度等,比430鋼抗鹽溶液體性強。一、X6CrMo17-1對應牌號:1、國標GB-T標準:數字牌號:S11790、新牌號:10Cr17Mo、舊牌號&#x…...
软件测试是个人就能做?恕我直言,你可能是个“纯粹”的测试工具人,BUG收集器
作为过来人的我和你说说软件测试的真正情况。 前言 一个软件做出来,最不能少的是谁?毫无疑问是开发,开发是最了解软件运作的那个人,早期就有不少一人撸网站或者APP的例子,相当于一个人同时是产品、研发、测试、运维等…...
递归算法(recursion algorithm)
递归算法 什么是递归算法 在过程或者函数里调用自身的算法; 递归算法(recursion algorithm),通过重复将问题分解为同类的子问题而解决问题的方法, Java中函数可以通过调用自身来进行递归,大多数编程语句…...
VScode下 ESP32 下载程序
ESP32-S3 下载方式可以通过UART0 下载,USB 下载,JTAG下载,还可以使用WIFI进行远程OTA升级程序。插件底栏按键介绍:①选择串口端口号,如COM3; ②选择芯片型号; ③工程idf设置,相当于menuconfig; …...
黑苹果日历
黑果日历 2023/2/27 总结 安装流程 制作启动U盘2017年,本来去当兵,结果近视👓没验上。父母我还想学什么?我想到了黑客操作电脑的画面,感觉特别酷。 2017年有了第一台自己的笔记本,是小米游戏本࿰…...
python+pytest接口自动化框架(5)-requests发送post请求
在HTTP协议中,与get请求把请求参数直接放在url中不同,post请求的请求数据需通过消息主体(request body)中传递。且协议中并没有规定post请求的请求数据必须使用什么样的编码方式,所以其请求数据可以有不同的编码方式,服务端通过请…...
Linux 进程:进程控制
目录一、进程创建1.fork2.vfork二、进程终止三、进程等待四、进程替换1.理解程序替换2.子进程在程序替换中的作用Linux的进程控制分为四部分: 进程创建进程终止进程等待进程替换 一、进程创建 常见的创建进程的函数有两个: pid_t fork(void)pid_t vf…...
过滤器的创建和执行顺序
过滤器的创建和执行顺序 8.1.1创建并配置过滤器 P143 重点是如何创建并配置(xml) 1.创建 public class EncodingFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFil…...
JDK1.8 ConcurrentHashMap
数据结构锁sizeCtlconcurrencyLevelForwardingNode、ReservationNode扩容get、put、removehashmap:线程不安全 hashtable:通过synchronized保证线程安全但效率低。强一致性 ConcurrentHashMap:弱一致性 数据结构 ConcurrentHashMap为node数…...
参考 Promise/A+ 规范和测试用例手写 Promise
前言 这可能是手写promise较清晰的文章之一。 由浅至深逐步分析了原生测试用例,以及相关Promise/A规范。阅读上推荐以疑问章节为切入重点,对比Promise/A规范与ECMAScript规范的内在区别与联系,确定怎样构建异步任务和创建promise实例。然后开…...
yolov5数据集制作
yolov5 数据集的格式 每个图像的标注信息存储在一个独立的txt文件中每个txt文件的名称应该与其对应的图像名称相同,只是文件扩展名不同。例如: 对于名为“image1.jpg”的图像,其标注信息应存储在名为“image1.txt”的txt文件中。 在每个txt文件中,每一行表示一个对象的标注…...
主板EC程序烧写异常致无法点亮修复经验
主板型号:Gigabyte AB350M-Gaming3 官网上明确写着支持R5 5500,但按照如下步骤实践下来实际是不支持的 升级biosF31到F40版本的注意事项: 步骤: 1 使用Q-Flash先将bios升级到f31版本;2 然后下载提示中的ECFW Update To…...
【Java爬取赛事网站】命令行输出(仅供学习)
Java爬取赛事网站 Java爬取赛事网站Java爬取赛事网站参与社区的问题回答Gitcode项目地址PSP表格解题思路描述问题接口设计和实现过程编写中的测试关键代码展示性能改进单元测试异常处理心路历程与收获参与社区的问题回答 问题回答这个作业属于哪个课程软件工程-23年春季学期这…...
redis主从复制原理
在 Redis 中,我们可以通过 SLAVEOF 命令或者 slaveof 选项,让一个服务器去复制另一个服务器,被复制的服务器称为“主服务器”,发起复制的服务器称为“从服务器”,由两种服务器组成的模式称为“主从复制”。 主从复制原…...
buu刷题(第一周)
目录 [DDCTF 2019]homebrew event loop action:trigger_event%23;action:buy;5%23action:get_flag; [CISCN2019 华东南赛区]Web4 [RootersCTF2019]babyWeb [GWCTF 2019]mypassword [NESTCTF 2019]Love Math 2 [BSidesCF 2019]Pick Tac Toe [RootersCTF2019]ImgXweb [SW…...
算法训练营 day62 单调栈 每日温度 下一个更大元素 I
算法训练营 day62 单调栈 每日温度 下一个更大元素 I 每日温度 739. 每日温度 - 力扣(LeetCode) 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,…...
ChIP-seq 分析:Peak 注释与可视化(9)
1. 基因注释 到目前为止,我们一直在处理对应于转录因子结合的 ChIPseq 峰。顾名思义,转录因子可以影响其靶基因的表达。 转录因子的目标很难单独从 ChIPseq 数据中确定,因此我们通常会通过一组简单的规则来注释基因的峰: 如果峰与…...
ABB机器人配置DeviceNet总线IO板以及信号分配的具体方法示例
ABB机器人配置DeviceNet总线IO板以及信号分配的具体方法示例 基本步骤: 配置IO板分配IO信号这里以DeviceNet总线的DSQC652为例进行说明: 配置IO板的基本步骤: 配置IO板的型号 连接到总线 配置IO板的地址 (1台机器人可以配置多个IO板连接到DeviceNet总线,为了让机…...
2023 年网络安全漏洞的主要原因
网络安全漏洞已经并将继续成为企业面临的主要问题。因此,对于企业领导者来说,了解这些违规行为的原因至关重要,这样他们才能更好地保护他们的数据。 在这篇博文中,我们将概述 2023 年比较普遍的网络安全漏洞的主要原因。 云…...
剑指 Offer 34. 二叉树中和为某一值的路径
剑指 Offer 34. 二叉树中和为某一值的路径 难度:middle\color{orange}{middle}middle 题目描述 给你二叉树的根节点 rootrootroot 和一个整数目标和 targetSumtargetSumtargetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节…...
2023前端vue面试题(边面边更)
Vue中key的作用 vue 中 key 值的作用可以分为两种情况来考虑: 第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的…...
加强学院网站的建设与管理/发稿
2019独角兽企业重金招聘Python工程师标准>>> http_status_bad_request (400) the request could not be processed by the server due to invalid syntax. 因为语法不能被服务器处理 http_status_denied (401) the requested resource requires user authentica…...
网站做记录访客/百度手机应用市场
最近在做MIS管理系统中,对于数据列表展示前面要加上一个序号,全选等功能(本篇文章只解决在DataGrid前加序号问题);从网上也看到有 朋友对这方面的功能做了一些讲解,其功能都是一样,也没有什么好说;关键在于…...
手机网站设计机构/google入口
2020年注定是个不平凡的一年,疫情的影响下,全世界都在遭受疫情的冲击。在这种大环境下,晋陶机械的创始人---陶正勇,并不是坐以待毙,相反,他潜心研究、创新突破自己产业的瓶颈。顺应市场需求,助力…...
南宁企业免费建站/seo是什么部位
前文回顾:如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1)如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2)如何掌握openGauss数据库核心技术?…...
学做网站必须php吗/软文推广发布
开发环境:系统环境:龙芯1B开发板(mips32指令)、Linux 3.0.0内核编译环境:Ubuntu 10.04 ,gcc-3.4.6-2f本文要用到的相关文件(cramfs-1.1.tar.gz、yaffs2-d43e901.tar.gz、mtd-utils-1.0.0.tar.gz)下载:用户名与密码都是www.linuxid…...
用绿色做图标的网站/那个推广平台好用
目录: 1.为啥要做cmdb? 2.开发cmdb的思路和大概做法? 3.cmdb的四套方案? 一、为啥要做CMDB a.项目发开和上线场景? 流程: 产品经理调研需求 》定一个时间开发 》测试 》产品项目上线(运维) 传统做法: 运维解压文件…...