当前位置:首页 > 问答 > 正文

用Redis搞个登录功能,简单又快,还挺好用的那种感觉

说到用Redis搞登录功能,特别是想要那种“简单又快,还挺好用”的感觉,那核心思路就是别把Redis当成唯一存储,而是把它当成一个速度飞快的“临时工作台”,你的用户主要信息,比如账号、密码(当然是加密后的)、注册时间这些,还是得老老实实放在MySQL这类正经的数据库里,因为要保证数据的安全和持久,Redis呢,就专门用来处理那些高并发、需要快速响应的“热乎”数据。

最经典的应用就是管理用户的登录状态,也就是我们常说的Session,传统做法是把Session存在服务器内存或者数据库里,但这样要么有扩展性问题,一关机就没了,要么就是每次验证都得查数据库,速度慢,用Redis就完美解决了这两个痛点。

具体怎么搞呢?想象一下用户登录的流程:

用Redis搞个登录功能,简单又快,还挺好用的那种感觉

用户在前端输入账号密码,点击登录,后端服务接到请求,第一件事就是去MySQL数据库里核对账号密码对不对,如果不对,直接返回错误信息,如果对了,说明用户是合法的,这时候好戏开场,Redis要上场了。

第一步:生成一个“通行证”(Token) 登录成功后,后端需要生成一个唯一无规律、且足够复杂的字符串作为用户的“通行证”,这个就是Token,通常可以用UUID或者更安全的JWT(JSON Web Token)来生成,这个Token至关重要,它代表了这次登录会话的授权凭证。

第二步:把“用户信息”塞进Redis 生成了Token,接下来就要把和这次登录相关的信息存到Redis里,在Redis里,我们会把Token作为Key,那Value存什么呢?这里就是体现“好用”和灵活性的地方了,你不需要把用户的全部信息都存进去,那样既占空间又不安全,通常只需要存一些核心的、后续请求需要频繁用到的信息就行,

用Redis搞个登录功能,简单又快,还挺好用的那种感觉

  • userId (用户唯一ID,最重要的)
  • username (用户名,用于显示)
  • loginTime (登录时间,用于记录) 你可以把这些信息组装成一个JSON字符串存进去,更简单直接的方式是,Value里只存userId,然后需要其他信息时,再用这个userId去数据库查,这取决于你对性能和代码复杂度的权衡,但只存userId是最简单清晰的。

存的时候,最关键的一步是给这个Key设置一个过期时间(TTL),比如设置成30分钟或者2小时,这步太重要了,它实现了“自动踢人下线”的功能,用户如果一直不操作,过了这个时间,这个Key就会自动从Redis里消失,下次用户再请求时,就会发现登录状态失效了,需要重新登录,这既安全又省去了我们手动清理的麻烦,Redis这个自动过期的特性用起来特别爽,就一行命令的事。

在Redis里,一条数据看起来大概是这样的:

  • Key: session:token (session:abcd1234efgh5678)
  • Value: 12345 (用户的ID)
  • TTL: 1800秒 (30分钟)

第三步:把“通行证”交给前端 后端把Token返回给前端,前端拿到后,就需要在后续的每一个需要认证的请求里,都带上这个Token,通常的做法是放在HTTP请求的Header里,Authorization: Bearer abcd1234efgh5678

用Redis搞个登录功能,简单又快,还挺好用的那种感觉

第四步:验证请求 每当用户访问需要登录的页面或接口时,前端都会自动带上这个Token,后端接口的逻辑就变得非常轻量和高效了:

  1. 拦截请求,从Header里取出Token。
  2. 拿着这个Token,去Redis里查一下,看看有没有对应的Key存在,命令就是简单的 GET session:abcd1234efgh5678
  3. 如果查不到,说明Token无效或者已经过期了,直接返回“未登录”的错误。
  4. 如果查到了,就拿到了对应的userId,这时候,你可以选择直接把userId塞到请求上下文里,让业务逻辑去用,或者,如果Value里存了更多信息,也可以直接使用,连数据库都省得查了。

这个过程非常快,因为全程几乎只和Redis做一次简单的键值查询,而Redis的速度是出了名的快,每秒处理十万次这种请求都轻轻松松,这就实现了“快”的感觉。

“挺好用”的感觉还体现在哪里?

  1. 单点登录(SSO)简单化:同一个用户不能在多处登录?太简单了,在用户登录时,除了上面的操作,你还可以在Redis里设置一个以userId为Key的记录(user_login_status:12345),值就是最新的Token,这样每次新登录时,都把旧的顶掉,验证时不仅检查Token是否存在,还检查这个Token是不是和当前用户最新的Token一致,不一致就说明在别处登录了,就把当前的请求踢下线。
  2. 管理用户在线状态:你想知道有多少用户在线?在Redis里用 SCAN 命令模糊查询一下所有 session:* 开头的Key有多少个,就大概知道了,这比去数据库里查日志快多了。
  3. 强制下线:如果想手动踢掉某个用户(比如管理员操作),直接去Redis里删除那个用户对应的Session Key就行了,立刻生效。

用Redis搞登录功能的精髓就是“好钢用在刀刃上”,MySQL管长久存储,Redis管高速缓存和会话状态,通过Token机制和Redis的过期特性,你就能轻松搭建一个既能承受高并发、又具备自动管理登录状态能力的系统,整个过程代码写起来不复杂,思路也清晰,跑起来效果立竿见影,自然就给人一种“简单又快,还挺好用”的爽快感。