点击关注公众号,实用技术文章及时了解

前言

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

结合昨天的网关相关知识食用更佳

业务图解

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

流程解读

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

  1. 填写手机号

  2. 发送验证码

  3. 填写验证码

  4. 勾选新用户自动注册

服务端-用户验证

  1. 验证账号验证码是否正确

  2. 验证用户是否存在(不存在出初始化用户信息)

  3. 完成验证生成token

  4. 将token返回给客户端

用户信息设计

验证流程图解

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

关于token过期时间

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

关于业务请求token验证

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

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

关于登出操作

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

关于匿名请求(免登录)

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

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

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

技术实现

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

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

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

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

请求次数检查代码实现

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 {@Autowiredprivate 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就会进行拦截。

总结

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

感谢阅读,希望对你有所帮助 :) 

来源:juejin.cn/post/7004756545741258765

推荐

主流Java进阶技术(学习资料分享)

Java面试题宝典

加入Spring技术开发社区

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!

图解用户登录验证业务流程(推荐)相关推荐

  1. 【209期】图解用户登录验证业务流程(面试应答推荐)

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...

  2. php 语法验证_PHP用户登录验证模块

    这篇文章介绍的内容是关于PHP用户登录验证模块 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 实现用户登录 >>>1 创建登录表单 登录表单的HTML代码如下: U ...

  3. 使用SSH框架实现用户登录验证

    今天,写一个非常简单的通过struts+hibernate+spring的集成来实现用户登录验证的例子,让大家了解一下三者是如何是整合的. 我们可以通过myeclipse的向导,生成相应的环境搭建,如 ...

  4. ajax登录验证的原理,ajax用户登录验证-get和post提交方式,与工作原理—2018-8-15...

    ajax用户登录验证: 实例 html> Ajax实战:表单验证 用户登录 邮箱: 密码: 提交 let btn = document.getElementsByTagName('button' ...

  5. python登录验证程序_Python模拟用户登录验证

    本文实例为大家分享了Python模拟用户登录验证的具体代码,供大家参考,具体内容如下 1.功能简介 此程序模拟用户登录验证的过程,实现用户名输入.黑名单检测.用户有效性判别.密码输入及验证等.用户在3 ...

  6. JavaWeb 实验 Servlet用户登录验证

    实验2.2 Servlet用户登录验证 实验内容: 编写JSP程序,实现用户提交登录表单给Servlet,由Servlet 查询数据库(模拟查询,不用真的连接数据库查询),对用户是否存在进行验证. 实 ...

  7. 数据库用户登录验证及注册功能实现

    数据库用户登录验证及注册功能实现 1.mysql数据库安装 2.解决navicat连接mysql的密码错误问题 3.创建数据库.用户表.插入数据 (1)进入mysql数据库 (2) 创建数据库dnn_ ...

  8. 基于 JSP + Servlet 的用户登录验证

    综合案例--基于 JSP + Servlet 的用户登录验证 [例6-1] 实现一个简单的用户登录验证程序,如果用户名是 abc ,密码是 123,则显示欢迎用户的信息,否则显示"用户名或密 ...

  9. php链接mysql实例之用户登录验证以及使用cookie登录

    这篇博客实现用户登录验证以及使用cookie登录,它承接了前面的几个博客: 1. php连接mysql实例之新用户注册实现 2. php连接mysql实例之后台列表显示已注册的用户信息 3. php连 ...

最新文章

  1. glibc和ulibc的区别
  2. MySQL 触发器错误
  3. Linux设置路由器ip租约时间,入坑Linux-day15(使用DHCP动态管理主机地址)
  4. java knn kd树_KNN算法之KD树(K-dimension Tree)实现 K近邻查询
  5. ionic2 html 转义,ionic2 基于ngx-translate实现多语言切换,翻译
  6. 解决eclipse中jsp没有代码提示问题
  7. 八、Vue cli3详解学习笔记
  8. 跨设备链路聚合_路由与交换技术(华为设备)第五讲---链路聚合
  9. valgrind 内存泄漏_应用 AddressSanitizer 发现程序内存错误
  10. 用户zabbix@localhost的访问被拒绝(使用密码:yes)_Coinbase意外地保存了3420个客户的未加密密码...
  11. 深入浅出VC++串口编程--短信应用开发
  12. rdt1.0,rdt2.0,rdt2.1,rdt2.2,rdt3.0
  13. 保定华电计算机考研真题,华北电力大学(保定)离散数学试题(含2005年真题)...
  14. Mac OSX终极瘦身
  15. 企业内的ITSM软件与OA系统有什么区别和关系?
  16. 【路科V0】systemVerilog基础3——字符串类型
  17. 在WORD中批量修改图片大小
  18. LNK1104:无法打开文件kernel32.lib的解决方法解决方法
  19. 数字通信系统中带宽的概念
  20. 一个轻量级的RGB颜色选择器--jscolor

热门文章

  1. 小米MIX 3 5G版入网工信部:更新内存版本
  2. “耳边的AI助理” 出门问问发布TicPods 2系列头控真无线耳机
  3. 炒鞋火了?单日成交金额超新三板!
  4. 令人窒息!iPhone充电时自燃烧毁房子,到底是谁的锅?
  5. 汽车金融平台百金贷宣布良性退出网贷业务
  6. 一家贩卖8亿份个人简历的公司 现已人去楼空
  7. 聊天宝解散,多闪、马桶MT还会远吗?
  8. 故宫夜场门票被炒到3000元一张?网站被挤崩 故宫如此回应...
  9. 35岁遭遇互联网公司无情裁员,面试屡屡碰壁,原因竟是……
  10. Android Studio创建签名文件,打包apk,多渠道打包