首页 > 其他分享 >一文搞懂用户登录验证流程(附图)

一文搞懂用户登录验证流程(附图)

时间:2022-09-18 23:55:53浏览次数:127  
标签:缓存 一文 登录 验证 用户 附图 token 搞懂 请求

前言

本文通过图示及代码的方式介绍用户登录流程及技术实现,内容包括用户登录,用户验证,如何获取操作用户的信息以及一些黑名单及匿名接口如何免验证相关的实现。

结合网关相关知识食用更佳

业务图解

对于用户登录来说、涉及到了用户注册、登录验证几个方面,通过流程图演示如何处理(新用户/老用户)登录

image.png

流程解读

  • 客户端-登录界面(通常手机验证码登录)

    1.填写手机号 2.发送验证码 3.填写验证码 4.勾选新用户自动注册

  • 服务端-用户验证

    1.验证账号验证码是否正确 2.验证用户是否存在(不存在出初始化用户信息) 3.完成验证生成token 4.将token返回给客户端

用户信息设计

字段描述类型是否唯一
telephone手机号varchar
nickname昵称varchar根据业务决定是否可重复
account账号varchar
password密码varchar
create_time创建时间datetime
modify_time修改时间datetime
...省略小程序授权码等等、根据自身业务进行增加

验证流程图解

image.png

登录验证流程涉及到了两个接口,两个缓存。1.获取验证码接口,给手机号发送验证码并设置验证码缓存,设置过期时间;2.登录接口,提交手机号及验证码,读取缓存进行匹配验证,成功则生成token返回给客户端,客户端登录成功,登录后请求头携带token进行业务请求即可。

关于token过期时间

通常我们token的过期时间是根据客户端的类型来定义的,app的过期时间会更长一些(通常一个星期),web端过期时间以小时为单位,如果控制过期时间可以将web登录和app登录拆分为两个接口(能够分流,接口压力更小),或者是根据请求头信息进行判断即可,是移动端就设置7天,是web端就设置两小时。

关于业务请求token验证

登录成功后,客户端每次请求都会携带token,通常我们会有一个网关来进行token验证,网关用于登录验证的核心就是登录成功后写入的token作为key,值为用户基础信息的缓存,图解如下:

image.png

验证成功后,重写内部请求头,将用户的的id,账号,昵称信息放入请求头中,这样可以方便业务系统获取当前操作用户信息以及权限控制等等

关于登出操作

用户携带token请求登出接口,登出接口对token对应的缓存进行删除操作,返回401即可,客户端获取到401就会跳转到登录页面

关于匿名请求(免登录)

通常匿名请求放行有两种方案,1.授权token,为token设置单位时间内请求次数;2.配置路径放行规则,对请求接口路径进行正则匹配,符合正则规则的进行放行

方案1:授权token,限制单位时间请求次数

优点就是虽然是免登录接口,但是接口的操作对象可以追溯,请求次数可控,避免被非法利用;缺点就是需要更多的编码及配置工作

技术实现

  • 1.提供一个授权token管理页面,主要管理token使用者,token的值,单位时间访问次数(如每分钟60次)

  • 2.增删改查,将授权token存放到缓存中,使用map进行存储,key为token,值为每分钟访问次数

  • 3.单位时间计数缓存,过期时间为1分钟

这时候我们需要在上面的验证流程图基础上进行升级

image.png

请求次数检查代码实现


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**

  • 授权token请求限制缓存

  • @author 热黄油啤酒

  • @since 2021-11-01
    */
    @Component
    public class AuthTokenRequestLimitCache {

    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;

    private static final String AUTH_TOKEN_LIMIT_KEY_PREFIX = "auth_token_limit";

    /**

    • 请求次数+1并检查是否超限
    • @param token
    • @return 是否放行
      */
      public boolean incrementWithCheck(String token) {
      // 1.获取token请求次数限制,获取为null代表授权配置已被修改,此token已经不具备权限
      Integer limit = getLimit(token);
      if (limit == null) {
      return false;
      }
      // 2.组装缓存key,读取缓存
      String key = String.join(":", AUTH_TOKEN_LIMIT_KEY_PREFIX, token);
      Integer count = redisTemplate.opsForValue().get(key);
      // 3.没有值代表一分钟内没有请求产生了
      if (count == null) {
      // 初始化值
      redisTemplate.opsForValue().increment(key);
      // 设置过期时间
      redisTemplate.expire(key, 1L, TimeUnit.MINUTES);
      return true;
      }
      // 自增并获取当前值 大于限制的话 返回false 网关过滤器返回提示信息(如请求过于频繁)
      Long inc = redisTemplate.opsForValue().increment(key);
      return inc <= limit;
      }

    /**

    • 获取限值
    • @param token
    • @return
      */
      public Integer getLimit(String token) {
      Object limit = redisTemplate.opsForHash().get("auth_token_limit", token);
      return limit == null ? null : (Integer) limit;
      }
      }
      复制代码

对于授权接口,通常是只允许get操作,对数据进行提交或者更新是不被允许的,当然这个是业务层面的,最终取决于系统设计

方案2:请求路径正则校验

我们在网关的配置文件中增加匿名接口规则,请求到网关时,检查请求的路径是否符合匿名接口规则,是则放行,不是则进行token校验,方案比较简单,只需要对网关进行处理即可。

关于黑名单

对于一个系统来说,黑名单是最后一道关卡,所以为了安全我们需要对问题用户进行黑名单操作,具体实现也比较简单

  • 1.用户管理页面提供一个拉黑的按钮,拉黑后,这些用户的id会存储到一个set集合中去
  • 2.登录时候检查用户是否在黑名单中,是则拒绝登录并提示
  • 3.如果用户已经登录后进行拉黑操作,网关会在鉴权通过后检查用户是否在黑名单中,是则删除token对应缓存,返回401,401就会跳到登录页,步骤2就会进行拦截。

总结

用户系统是非常基础的系统,但是很多程序员工作中可能并没有真正的参与到用户系统的开发,通过此文可以对用户登录流程及配套功能有一个全面的了解。

其它登录鉴权相关文章

阿里需求挑战-十分钟内连续登录5次失败,需要等待30分钟才能登录【附图】 - 掘金 (juejin.cn)

快速搭建一个网关服务,动态路由、鉴权看完就会(含流程图) - 掘金 (juejin.cn)

来源:https://juejin.cn/post/7025768845075808286

标签:缓存,一文,登录,验证,用户,附图,token,搞懂,请求
From: https://www.cnblogs.com/konglxblog/p/16706306.html

相关文章

  • 一文理解golang中的链表
    每节运煤车就是单链表里的元素,每节车厢里的煤炭就是元素中保存的数据。前后车通过锁链相连,作为单链表运煤车,从1号车厢开始,每节车厢都知道后面拉着哪一节车厢,却不知道前面是......
  • Salesforce学习收藏贴!一文搞懂Salesforce角色、简档和权限集
     简档、角色和权限集共同决定Salesforce用户可以在Salesforce中查看和执行的操作。【安全和访问】算是Salesforce管理员认证考试中最棘手的模块之一,作为该模块的重要考......
  • 彻底搞懂this指向
    this是JavaScript中的一个关键字,但是又一个相对比较特别的关键字,不像function、var、for、if这些关键字一样,可以很清楚的搞清楚它到底是如何使用的。this会在执行上下文......
  • 怒啃 24 小时,终于搞懂上下文切换!
    大家好,我是树哥。对于服务器系统来说,上下文切换也是影响系统性能的一个重要因素。深入理解上下文切换的原理,有利于我们做好性能优化工作。今天我将带大家了解下上下文切换......
  • 一篇文章彻底搞懂snowflake算法及百度美团的最佳实践
    写在前面的话一提到分布式ID自动生成方案,大家肯定都非常熟悉,并且立即能说出自家拿手的几种方案,确实,ID作为系统数据的重要标识,重要性不言而喻,而各种方案也是历经多代优化......
  • 一文了解Makefile
    本篇翻译自《LearnMakefilesWiththetastiestexamples》,翻译主要是意译,加入了一些个人理解。熟练英文的朋友请直接阅读原文。链接见:https://makefiletutorial.com/#......
  • 一文带你认识AscendCL
    摘要:AscendCL(AscendComputingLanguage,昇腾计算语言)是昇腾计算开放编程框架,是对底层昇腾计算服务接口的封装。本文分享自华为云社区《【CANN文档速递09期】应用开发之推......
  • 【C标准库】详解fopen函数 一篇让你搞懂fopen函数
    创作不易,感谢支持!fopen函数头文件:stdio.h功能是打开一个文件,其声明格式是:FILE*fopen(constchar*filename,constchar*mode);文件指针名=fopen(文件名,使用文......
  • 一文搞懂测试左移和测试右移的 Why-How-What
    ⬇️点击“下方链接”,提升测试核心竞争力!>>更多技术文章分享和免费资料领取软件测试技术应当贯穿整个软件开发生命周期、对软件产品(包括阶段性产品)进行验证和确认的活动......
  • 一文解读研发效能
    本文主要澄清了敏捷开发、持续集成、持续交付1.0、持续交付2.0、持续部署、DevOps、研发效能七个概念,以便我们在后续相关工作和实践中能清楚地辨别。一张图区分 上......