Redis 实现分布式Session 登录相关细节

Redis 实现分布式Session 登录

借助 Redis 对 Session 信息进行统一的存储和管理,这样无论请求发送到哪台服务器,服务器都会去同一个 Redis 获取相关的 Session 信息,这样就解决了分布式系统下 Session 存储的问题。

  1. 【发送短信】校验手机号,如果校验手机号格式正确,那么就生成一个六位随机数字验证码,然后把这个六位数保存到 Redis 中,key 设置为业务前缀+手机号,value 就是 String 类型的随机数验证码,设定验证码的有效时间(2-3 分钟)防止这个 redis 中的数据越存越多。最后将验证码返回给前端。
  2. 【登录和注册】接下来用户输入手机号和验证码登录。登录时先校验手机号格式,校验格式通过后,之后根据前端发来的手机号(手机号就是 redis 中的 key 的一部分)从 redis 中获取验证码。
    a. 如果验证码一致(redis 保存的和用户输入的一致),那么就根据手机号去数据库查找用户是否存在。
    ⅰ. 如果数据库中有该用户,保存用户信息到 redis(便于后面逻辑的判断 比如登录判断、随时取用户信息,减少对数据库的查询)
    1. 随机生成一个 token(使用 UUID+一些业务前缀) 作为登录令牌,作为 redis 中的 key。
    2. 存储用户信息。【putall 方法】参数: key=token, Map(哈希表)。即以 Hash 存储到 redis
    3. 存储的时候也不能一直存一直存,需要设计用户信息的有效期,一段时间后就清除内存。
    4. 将这个 token 返回给客户端存储,以后每次发送请求的时候客户端就会携带。
      ⅱ. 如果数据库中没有该用户,那就创建新用户(补充一些用户名昵称之类的),保存到用户数据库,之后保存用户信息到 redis。
      b. 如果验证码不一致,返回失败,需要重新提交验证码手机号。
  3. 相当于之后用户的登录凭证就是 redis 中的 key(token) ,登录之后浏览器每次发送请求时,请求头就会携带含有 token 的 Cookie。那么服务端收到之后就可以通过 token 得到 redis 中存储的 value,如果得到了 value 就可以判断为登陆成功。
  4. 【后续请求时校验登录状态】后续的请求都会携带 cookie:token,通过 interceptor1 拦截器 1 拦截所有请求,之后获取 token,从而获取 redis 中的用户信息。如果成功获取到了,那么就将用户信息保存到 TreadLocal 中,然后刷新 token 有效期,之后放行。如果没有获取到用户信息,那么就直接放行(交给第二个拦截器处理)。
    之后通过 interceptor2 拦截器 2 拦截需要登录的路径,如果从 TreadLocal 中查询到用户,那么就放行,如果没查到,那么就拦截。那些不需要登录就能访问的东西,就不会被拦截了。

采用 Redis 里面的 Hash 数据结构存储:

● 对象的 String 数据结构是以 JSON 字符串的形式保存,更加直观,操作也更加简单,但是 JSON 结构会有很多非必须的内存开销,比如双引号、大括号,内存占用比 Hash 更高
● Hash 数据结构是以 Hash 表,也就是 hashkey-value 的形式保存,可以对单个字段进行CRUD更加灵活

为什么已经存在 redis 中了还需要存到 treadlocal?

  1. 减少服务器的交互,提升性能,
  2. 方便后续逻辑处理,比如:方便获取和使用用户信息,Redis获取用户信息是具有侵入性的

视频软件如何维护登录状态?

那就直接设计一个过期时间很久的 jwt,或者返回的时候制定 cookie 过期时间(这样 cookie 就会存在磁盘中,关闭浏览器也不会失去 cookie)。

JWT 如何设置过期时间?

JWTS 工具类里面setExpiration 设置。还需设置 header 中的签名算法,签名密钥。设置有效载荷 claims 等

什么时候用 JWT 什么时候用 cookie session?

session+cookies是基于web的,移动端用不了 cookie,所以移动端一些 api 用 jwt,开发 web 应用的话都可以。

Cookie Session JWT 会话跟踪技术对比

会话:

在 web 开发中,浏览器和服务器之间的一次连接就称之为会话。只要浏览器和服务器不断开连接,那么就是属于一个会话。那么如果一个浏览器在未关闭之前请求了多次服务器,那么这些请求属于同一个回话。

会话跟踪:

就是一种维护浏览器状态的方法。我们后端服务器需要识别多次请求是否来自于同一个浏览器,从而实现在多次请求之间共享数据。从而解决 HTTP 协议是无状态的协议的问题,去辨别多次请求是否属于同一个会话,从而在一次会话的多次请求之间共享数据。

Cookie 数据存储在浏览器(客户端会话跟踪技术)

比如第一次请求登录接口,顺利通过登录校验完成之后,我们就可以设置一个cookie【HttpServletResponse 的 addCookie 方法】在 cookie 当中我们可以来存储用户相关的一些数据信息。比如我可以在 cookie 当中来存储当前登录用户的用户名,用户的ID 等等。
服务器端在给客户端响应数据的时候,会将 cookie 响应给浏览器(放在响应头 Set-Cookie 中),浏览器接收到响应回来的 cookie 之后,会自动的将 cookie 的值存储在浏览器本地。接下来在后续的每一次请求当中,都会将浏览器本地所存储的 cookie 自动地携带到服务端(放在请求头 Cookie 中)。
接下来在服务端我们就可以去获取 cookie 。【HttpServletResponse 的 getCookie 方法】判断这个 cookie 中的值是否存在,如果不存在这个cookie,就说明客户端之前是没有访问登录接口的,那后续的页面也就不能被访问,只能让他访问登录界面;如果存在 cookie 的值,就说明客户端之前已经登录完成了。这样我们就可以基于 cookie 在同一次会话的不同请求之间来共享数据。
优点:是 HTTP 中支持的技术,浏览器对于 Cookie 的自动发送和接受存储都是自动的,不需要我们手动操作
缺点:

  1. 移动端的 APP 无法使用 cookie
  2. 不是很安全因为用户可以自己禁用 cookie
  3. 跨域的话不能用 cookie(协议,IP地址,端口三者缺一就是跨域)

Session 数据存储在服务器(服务端会话跟踪技术)

比如浏览器第一次请求服务器的时候,这时候服务器会创建一个会话对象 Session,可以往 Session 中存储一些数据,且每一个会话对象都有一个 JsessionID。【HttpSession 的 setAttribute()方法】
接下来服务器在给浏览器相应数据的时候,就会把 Session 的 ID 通过 Cookie 响应给浏览器(放在响应头 Set-Cookie 中,cookie 的名字是固定的 JsessionID ——代表的服务器端会话对象 Session 的 ID)浏览器会自动识别这个响应头,然后将 Cookie 存在浏览器本地。
接下来,在后续的每一次请求当中,都会将 Cookie 携带到服务端(放在请求头 Cookie 中)。服务器拿到 JSESSIONID 这个 Cookie 的值,也就是 Session 的ID。拿到 ID 之后,就会从众多的 Session 当中来找到当前请求对应的会话对象Session。【HttpSession 的 getAttribute() 方法】
这样就可以 通过 Session 会话对象,在同一次会话的多次请求之间来共享数据了
优点: Session 是存储在服务端的,安全
缺点:
1.服务器集群不能直接用 Session。请求->负载均衡服务器->后端服务器 tomcat 集群
2.还有 Cookie 的问题:
a. 不能跨域(IP 地址,端口号,协议)
b. 用户可以自己禁用 Cookie
c. 移动端不能用 Cookie

令牌技术

令牌,其实它就是一个用户身份的标识,其实本质就是一个字符串。
在请求登录接口的时候,如果登录成功,我就可以生成一个令牌,令牌就是用户的合法身份凭证。接下来我在响应数据的时候,我就可以直接将令牌响应给前端。
前端程序接收到令牌之后,就需要将这个令牌存储起来。这个存储可以存储在 cookie 当中,也可以存储在其他的存储空间(比如:localStorage)当中。
接下来,在后续的每一次请求当中,都需要将令牌携带到服务端。携带到服务端之后,接下来我们就需要来校验令牌的有效性。如果令牌是有效的,就说明用户已经执行了登录操作,如果令牌是无效的,就说明用户之前并未执行登录操作。
如果是在同一次会话的多次请求之间,我们想共享数据,只需要将共享的数据存储在令牌当中就可以了。
优点:1. 支持 PC 端 支持移动端
2. 解决了集群环境下的认证问题(因为不需要在服务器端存储数据)
3. 减轻了服务器的存储压力(令牌存储在客户端)
缺点:1. 需要自己实现令牌的生成,令牌的传递,令牌的校验

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

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

相关文章

centos 中使用 kubekey 安装 k8s v1.22.12 支持 GPU 调用

环境准备: https://blog.csdn.net/m0_64519023/article/details/138184970 生成配置文件: 中间需要执行 ./kk create config --with-kubernetes v1.22.12 这个命令生成配置文件,保留生成的配置文件中 spec: hosts 下的 node1,将…

NLP自然语言处理和应用场景介绍

【A】NLP(Natural Language Processing,自然语言处理)是计算机科学与人工智能领域的一个分支,旨在让机器能够理解、解释、生成人类语言。它涵盖了语言文本的语法、语义、语用、语境等方面的处理。 NLP的具体应用场景包括但不限于…

双向链表专题

文章目录 目录1. 双向链表的结构2. 双向链表的实现3. 顺序表和双向链表的优缺点分析 目录 双向链表的结构双向链表的实现顺序表和双向链表的优缺点分析 1. 双向链表的结构 注意: 这⾥的“带头”跟前面我们说的“头节点”是两个概念,带头链表里的头节点…

C#描述-计算机视觉OpenCV(3):重映射

C#描述-计算机视觉OpenCV(3):重映射 前言色彩波形图像重映射 前言 C#描述-计算机视觉OpenCV(1):基础操作 C#描述-计算机视觉OpenCV(2):图像处理 在前文中,描…

读取文件例题总结 python

主要是读取文件的操作,结合字典,列表,集合的综合例题 主要思路:先看文件结构 根据文件结构 划分 然后保存到列表中(一般是二维列表) 然后再保存到字典中进行一些列操作 1…学生成绩分析 #1.学生成绩分析…

pycharm批量注释或取消多行

1. 背景和介绍 在我们编写Python代码的过程中,注释是非常重要的。它可以帮助我们理解代码的逻辑、功能和用法,并且方便其他开发者阅读和维护代码。然而,在大型项目中,有时需要批量注释或取消注释多行代码,手动操作会非…

UI-Diffuser——使用生成性人工智能的UI原型设计

概述。 移动UI是影响参与度的一个重要因素,例如用户对应用的熟悉程度和使用的便利性。如果你有一个类似的应用程序,你可能会选择一个具有现代、好看的设计的应用程序,而不是一个旧的设计。然而,要从头开始研究什么样的UI最适合应…

Java中使用Redis实现分布式锁的三种方式

1. 导语 随着软件开发领域的不断演进,并发性已经成为一个至关重要的方面,特别是在资源跨多个进程共享的分布式系统中。 在Java中,管理并发性对于确保数据一致性和防止竞态条件至关重要。 Redis作为一个强大的内存数据存储,为在Java应用程序中实现分布式锁提供了一种高效的…

Go图片列表

需求 在一个页面浏览目录下所有图片 代码 package mainimport ("net/http""fmt""io/ioutil""sort""strings""strconv" )func handleRequest(w http.ResponseWriter, r *http.Request) {fmt.Println(r.Proto &…

静态库、动态库回顾

回顾一下库相关的知识点&#xff0c;总结备忘一下。在某种情况下&#xff0c;你有了如下的代码&#xff0c;结构如下 //pra.h #include <stdio.h> void test_01(); //pra.c #include "pra.h" void test_01() {printf("xxxxxxx----->%s %s()\n",…

typescript类型检查和原始类型

typescript类型检查和原始类型 类型检查 非严格类型是typescript默认的类型检查模式&#xff0c;在该模式下&#xff0c;类型检查的规则相对轻松&#xff0c;不会对undefined和null值做过多的限制&#xff0c;允许将undefined和null值赋给string类型的变量。进行JavaScript代…

【ChatGPT with Date】使用 ChatGPT 时显示消息时间的插件

文章目录 1. 介绍2. 使用方法2.1 安装 Tampermonkey2.2 安装脚本2.3 使用 3. 配置3.1 时间格式3.2 时间位置 4. 反馈5. 未来计划6. 开源协议7. 供给开发者自定义修改脚本的文档7.1 项目组织架构7.2 定义新的 Component(1) 定义一个新的 Component 类(2) 注册该 Component 7.3 一…

ICode国际青少年编程竞赛- Python-1级训练场-基本操作

ICode国际青少年编程竞赛- Python-1级训练场-基本操作 1、 Dev.step(3)2、 Dev.step(1)3、 Dev.step(7)4、 Dev.step(-1)5、 Dev.step(-5)6、 Dev.step(3) Dev.step(-8)7、 Dev.turnRight() Dev.step(1)8、 Dev.turnLeft() Dev.step(1)9、 Dev.step(4) Dev.tur…

自动找出字符串中有符号数字

需求 代码 class Solution:def myAtoi(self, s: str) -> int:s s.strip() # 删除首尾空格if not s: return 0 # 字符串为空则直接返回res, i, sign 0, 1, 1int_max, int_min, bndry 2 ** 31 - 1, -2 ** 31, 2 ** 31 // 10if s[0…

2024年 Java 面试八股文——SpringMVC篇

目录 1.简单介绍下你对springMVC的理解? 2.说一说SpringMVC的重要组件及其作用 3.SpringMVC的工作原理或流程 4.SpringMVC的优点 5.SpringMVC常用注解 6.SpringMVC和struts2的区别 7.怎么实现SpringMVC拦截器 8.SpringMvc的控制器是不是单例模式&#xff1f;如果是&am…

B树:原理、操作及应用

B树&#xff1a;原理、操作及应用 一、引言二、B树概述1. 定义与性质2. B树与磁盘I/O 三、B树的基本操作1. 搜索&#xff08;B-TREE-SEARCH&#xff09;2. 插入&#xff08;B-TREE-INSERT&#xff09;3. 删除&#xff08;B-TREE-DELETE&#xff09; 四、B树的C代码实现示例五、…

蓝桥杯练习系统(算法训练)ALGO-953 混合积

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 众所周知&#xff0c;人人都在学习线性代数&#xff0c;既然都学过&#xff0c;那么解决本题应该很方便。   宇宙大战中&…

oracle杀死锁时如果是多机并行怎么查

在Oracle中&#xff0c;当处理多机并行的锁问题时&#xff0c;查找和杀死锁定的会话可能涉及到跨多个数据库实例或服务器的操作。以下是一些建议的步骤和查询&#xff0c;帮助你在多机并行的环境中查找和杀死锁&#xff1a; 确定锁定对象&#xff1a; 首先&#xff0c;你需要…

MongoDB聚合运算符:$substr

MongoDB聚合运算符&#xff1a;$substr 文章目录 MongoDB聚合运算符&#xff1a;$substr语法使用举例 $substr聚合运算符返回字符串的子串&#xff0c;子串是从指定索引位置开始并包含指定数量的字符&#xff0c;索引是从零开始。自3.4版本起 $substr已弃用&#xff0c;目前 …

K8s: Helm搭建mongodb集群(1)

mongodb 集群搭建 mongdb 部署前 需要创建 pvc, pv 和 sc&#xff0c;如果在云上会自动创建helm 应用中心: https://artifacthub.io 1 &#xff09;Helm 安装 mongodb A. 无本地存储配置&#xff0c;重启数据消失 在 https://artifacthub.io/packages/helm/bitnami/mongodb…