Redis在登录接口中实现token时间的自适应增长

本篇文章前置知识,jwt令牌有一定了解,对spring有一定了解,对登录接口的实现有一定了解。

Redis在登录接口中的应用

     在我们平时写登录接口的时候,大家可能都会习惯性的说上一句,很简单哇。不就是前端像后端发送一个账号密码的请求,然后后端验证请求后,返回一个jwt令牌给前端,最后给令牌设置一个3天的过期时间,这样不就写完了吗。

    但是大家可能忽略了一个我们平时很常见的问题, 就是在上述操作中,我们jwt的令牌过期时间是写死了的。想象一个场景,我们在一次oj竞赛网站中,竞赛时间要到了,我们点击提交,结果jwt的令牌时间刚好结束了,那我们不得骂死这个开发哇。

所以为了解决上述的一个问题,这里我们需要用其他组件来对返回的Token进行一个存储和叫校验,这个组件必须得满足,有存储功能,可以设置过期时间,同时因为会反复查询,所以必须要速度快。 Redis当然就是最佳人选啦。

这里讲一下大概得流程

开发思路

     我们在后端生成jwt令牌的时候,将userId作为jwt中的存储内容进行传入,生成jwt令牌,同时将userId作为key, 敏感信息作为value 传入进入Redis数据库中,同时设置过期时间,要是用户调用接口的时候在Redis中进行一个查询,看是否能通过userId也就是Redis中的key来查到相应value,要是能查到,则表示当前用户为登录状态,同时在每一次通过查询之后,对接口进行一个剩余时间(redis中ttl)的判断,要是剩余时间不长,则对Redis中的数据进行延长,以达到一个重置登录状态的效果

这里我们的开发环节就写部分伪代码。

创建生成jwt令牌的工具类

    这里就当大家对jwt有一定了解了, 因为jwt中payload 部分是可以被解码的。所以我们不能用jwt进行敏感信息的存储,但是我们可以用jwt来存储用户的身份标识。我们首先进行jwt令牌的创建其中claims就是jwt可以存储的对象,(网上可以搜到常用工具)

 /*** ⽣成令牌** @param claims 数据* @param secret 密钥* @return 令牌*/public static String createToken(Map<String, Object> claims, String secret){//点进去HS512下面的算法全是非对称加密String token =Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512,secret).compact();return token;}/*** 从令牌中获取数据** @param token 令牌* @param secret 密钥* @return 数据*/public static Claims parseToken(String token, String secret) {returnJwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}

有了创建jwt的方法  

我们假设后端已经完成了 验证用户账号密码的一个校验 

此时调用createToken方法我们就可以进行Token的创建了 这里的Login对象为存储的敏感对象,我们可以自定义里面的字段

   public String createToken(Long userId, String secret){//创建jwt令牌, 令牌中存储userIdMap<String, Object> claim = new HashMap<>();claim.put("userId", userId);String token = JwtUtils.createToken(claim, secret);//这里的Login对象为自定义对象,可以存储用户的敏感信息,比如用户身份之类的Login login = new Login();login.setSusceptible(1);//最后2个参数为自己设置这里是伪代码redisTemplate.opsForValue().set(userId, login, timeout, timeUnit);return token;}

完成上述步骤基本的开发工作其实已经完成了,此时我们每一次前端发来请求之后我们就可以进行验证啦,当时要是项目是分布式项目的话,可以在gateway网关中完成拦截,单体架构可以就使用spring自带的拦截器就好了

@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//先获取请求参数String url = request.getRequestURI();// 跳过不需要验证的路径 登录 和 测试等等if (......) {return true;}//从http请求头中获取token 进行身份认证 这里getToken()为自定义的方法啊String token = request.getToken();//先判断是否有令牌if (StrUtil.isEmpty(token)) {throw new Exception("令牌不能为空")}//获取令牌中信息 解析     payload中信息Claims claims;claims = JwtUtils.parseToken(token, secret); //获取令牌中信息 解析     payload中信息//令牌解析失败,可能已经被篡改过了if (claims == null) {throw new Exception("令牌已过期或验证不正确!");}//解析成功之后String userId = JwtUtils.getUserKey(claims); //获取jwt中的key//redis中是否存在jwt来判断令牌是否过期boolean isLogin = redisService.hasKey(userId);//Redis中不存在前面存储的Login对象表示登录已经过期if (!isLogin) {throw new Exception("登录状态已过期");}//说明令牌正确 .......//这里可以对用户的敏感数据进行一些处理return true;}

当前前面只是完成了jwt令牌正确性和完整性的一个校验。在处理完令牌之后还有一步很重要的内容就是判断当前令牌剩余的时候,要是剩余的时间少于一个规定值,我们就对令牌进行延长,要是长期不操作,jwt令牌就会失效。

我们来完善延长方法

private boolean exTime(HttpServletRequest request,String userid){//获取TokenString token =request.getHeader(HttpConstants.AUTHENTICATION);//找一个临界值 当时间小于临界值的时候进行一个延长 这里设定剩余120分钟是进行延长Long expire = redisService.getExpire(userid, TimeUnit.MINUTES);//180为自己设定的一个时间 可以随便设置一个L行的数 要是小于这个时间就进行延长if(expire != null && expire < 180L){redisService.expire(userid, CacheConstants.REDIS_EXP, TimeUnit.MINUTES);}return true;}

经过这一系列流程,登录接口的扩展就大致开发完成啦

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

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

相关文章

python编程知识(实现数据加密和解密)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

html 页面引入 vue 组件之 http-vue-loader.js

一、http-vue-loader.js http-vue-loader.js 是一个 Vue 单文件组件加载器&#xff0c;可以让我们在传统的 HTML 页面中使用 Vue 单文件组件&#xff0c;而不必依赖 Node.js 等其他构建工具。它内置了 Vue.js 和样式加载器&#xff0c;并能自动解析 Vue 单文件组件中的所有内容…

JDK 8 升级 17 及 springboot 2.x 升级 3.x 指南

文章目录 JDK 8 升级 17简介javax.* 包移到 jakarta.*maven pom 中更新 java 版本 springboot 2.x 升级 3.xspring-boot 与 cloud、alibaba-cloud 的版本对应redis 默认配置调整SpringBoot 3.x 整合 Querydsl其他注意事项 maven 及 maven 插件的版本升级maven 版本升级maven-co…

HUAWEI华为MateBook B5-420 i5 集显(KLCZ-WXX9,KLCZ-WDH9)原装出厂Windows10系统文件下载

适用型号&#xff1a;KLCZ-WXX9、KLCZ-WDH9 链接&#xff1a;https://pan.baidu.com/s/12xnaLtcPjZoyfCcJUHynVQ?pwdelul 提取码&#xff1a;elul 华为原装系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、华为浏览器、Office办公软件、华为…

握 手 问 题

目录 一&#xff1a;问题描述 二&#xff1a;思路: 三&#xff1a;代码&#xff1a; 四&#xff1a;结果&#xff1a;1204 一&#xff1a;问题描述 小蓝组织了一场算法交流会议&#xff0c;总共有50 5050 人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照…

C++解决:求排列数

描述 输入两个整数m,n&#xff0c;求m个数字中选n个数的排列数。&#xff08;1<n<m<50&#xff09; 输入描述 两个正整数m和n。 输出描述 一个正整数表示排列数。 用例输入 1 6 5 用例输出 1 720 AC code #include<bits/stdc.h> using namespace s…

Avatar 高清图传

Avatar HD VTX 是一款数字视频发射器&#xff0c;专为与 Caddx/Walksnail 的 Avatar HD 系统配合使用而设计。最初以 Walksnail 品牌销售&#xff0c;实际上是 CaddX FPV 的一部分。 这些 VTX 设计用于 Caddx/Walksnail 的 Avatar HD 系统&#xff0c;并可与 Avatar HD Goggle…

【OpenWrt(3)】内网搭建iperf3测速服务器

下载的iperf3 网站&#xff1a;https://iperf.fr/iperf-download.php Window地址&#xff1a;https://github.com/ar51an/iperf3-win-builds 安卓&#xff1a;https://gitee.com/hiyanyx/magic-i-perf 文章目录 下载的iperf3Windows 服务器启动安卓客户端启动参考 Windows 服务…

利士策分享,如何规划多彩的大学生活?

利士策分享&#xff0c;学习规划多彩的大学生活 踏入大学&#xff0c;如同开启一场充满未知与可能的旅程。 为了让这段旅程不仅充满学术的熏陶&#xff0c;还洋溢着生活的多彩与人际的和谐&#xff0c;我们需要精心规划&#xff0c;积极行动。 一、多彩规划&#xff1a;点亮大学…

【408数据结构】散列 (哈希)知识点集合复习考点题目

苏泽 “弃工从研”的路上很孤独&#xff0c;于是我记下了些许笔记相伴&#xff0c;希望能够帮助到大家 知识点 1. 散列查找 散列查找是一种高效的查找方法&#xff0c;它通过散列函数将关键字映射到数组的一个位置&#xff0c;从而实现快速查找。这种方法的时间复杂度平均为…

【小沐学OpenGL】Ubuntu环境下glut的安装和使用

文章目录 1、简介1.1 OpenGL简介1.2 glut简介1.3 freeglut 2、glut安装2.1 命令安装glut2.2 源码安装glut 3、glut测试3.1 测试1&#xff0c;版本打印3.2 测试2&#xff0c;绘制三角形3.3 测试3&#xff0c;VBO绘制三角形 结语 1、简介 1.1 OpenGL简介 OpenGL作为图形界的工业…

2024最新!Facebook手机版和网页版改名教程!

Facebook作为全球最大的社交平台之一&#xff0c;允许用户自定义名字和昵称。在Facebook更新姓名可以帮助您更好的展现账号形象。本文将为您提供详细的步骤指导&#xff0c;帮助您在手机APP和网页版上轻松完成Facebook改名操作。 Facebook手机版改名 打开Facebook APP并登录账号…

构建模块化的FastAPI应用: 从用户认证到角色控制

实现了用户身份验证及角色授权的基本功能。具体来说&#xff0c;当用户尝试访问某些资源时&#xff0c;系统会首先验证用户的身份&#xff0c;然后根据用户的角色来决定是否允许访问特定资源。例如&#xff0c;普通用户只能访问自己的信息&#xff0c;而管理员可以访问额外的管…

UnLua调用C++函数

一、UnLua调用C全局静态函数 1、新建C类MyLuaUtils&#xff0c;继承BlueprintFunctionLibrary,实现全局静态函数GetInt。 MyLuaUtils.h UCLASS() class LUASHOOTING_API UMyLuaUtils : public UBlueprintFunctionLibrary {GENERATED_BODY()UFUNCTION(BlueprintCallable)static…

Python 神器:wxauto 库——解锁微信自动化的无限可能

&#x1f4dd;个人主页&#x1f339;&#xff1a;誓则盟约 ⏩收录专栏⏪&#xff1a;机器学习 &#x1f921;往期回顾&#x1f921;&#xff1a;“探索机器学习的多面世界&#xff1a;从理论到应用与未来展望” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f…

GPIO 简介(STM32F407)

一、GPIO简介 什么是GPIO GPIO即通用输入输出端口&#xff0c;全称General Purpose Input Output&#xff0c;是控制或者采集外部器件的信息的外设&#xff0c;即负责输入输出。 它按组分配存在&#xff0c;每组最多16个IO口&#xff0c;组数视芯片而定。比如STM32F407ZGT6是…

【Python】Python 读取Excel、DataFrame对比并选出差异数据,重新写入Excel

背景&#xff1a;我在2个系统下载出了两个Excel&#xff0c;现在通过对下载的2个Excel数据&#xff0c;并选出差异数据 从新写入一个新的Excel中 differences_url rC:\Users\LENOVO\Downloads\differences.xlsx; //要生成的差异Excel的位置及名称 df1_url rC:\Users\LENOVO\Dow…

大数据新视界--大数据大厂之Java 与大数据携手:打造高效实时日志分析系统的奥秘

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Spring源码(3)Aware接口、初始化和销毁方法、@Scope、@Primary

1、目标 本文的主要目标是学习Spring源码中Aware接口、初始化和销毁方法、Scope注解、Primary注解的使用 2、Aware接口 Component public class MyBeanAware implements BeanNameAware, ApplicationContextAware {Overridepublic void setBeanName(String name) {System.out…

从JavaScript入门Go三

前情提要 上一章中我们讲了Go中的变量与函数&#xff0c;这一节我们说说Go中的逻辑语法for、if、switch。最近正好有空&#xff0c;正好给大家更新一下入门的第三章。 PS&#xff1a;没看过的第一章、第二章的小伙伴&#xff0c;可以进入下面的链接查看 从JavaScript入门Go一 从…