不出意外的话,我猜在座的各位同学,刚刚学编程的时候,80%以上的人写的第一个项目不是学生管理系统,就是用户的登录、注册;需求都是源于生活而高于生活,因为学生对这些场景最为熟悉,功能也相对简单,拿来练手最适合不过了;但是,一个看似小小的登录、注册功能,要想把他真正的做好,并不是一件容易的事情;本文通过图示及代码的方式介绍用户登录流程及技术实现,内容包括用户登录,用户验证,如何获取操作用户的信息以及一些黑名单及匿名接口如何免验证相关的实现。
对于用户登录来说、涉及到了用户注册、登录验证几个方面,通过流程图演示如何处理(新用户/老用户)登录。
图片
图片
图片
登录验证流程涉及到了两个接口,两个缓存:
通常我们 token 的过期时间是根据客户端的类型来定义的,app 的过期时间会更长一些(通常一个星期)。
web 端过期时间以小时为单位,如果控制过期时间可以将 web 登录和 app 登录拆分为两个接口(能够分流,接口压力更小),或者是根据请求头信息进行判断即可,是移动端就设置 7 天,是 web 端就设置两小时。
登录成功后,客户端每次请求都会携带 token,通常我们会有一个网关来进行 token 验证,网关用于登录验证的核心就是登录成功后写入的 token 作为 key,值为用户基础信息的缓存。
图解如下:
图片
验证成功后,重写内部请求头,将用户的的 id,账号,昵称信息放入请求头中,这样可以方便业务系统获取当前操作用户信息以及权限控制等等。
用户携带 token 请求登出接口,登出接口对 token 对应的缓存进行删除操作,返回 401 即可,客户端获取到 401 就会跳转到登录页面。
通常匿名请求放行有两种方案:
优点就是虽然是免登录接口,但是接口的操作对象可以追溯,请求次数可控,避免被非法利用;缺点就是需要更多的编码及配置工作。
技术实现:
这时候我们需要在上面的验证流程图基础上进行升级:
图片
请求次数检查代码实现: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请求限制缓存 */@Componentpublic 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 操作,对数据进行提交或者更新是不被允许的,当然这个是业务层面的,最终取决于系统设计。
我们在网关的配置文件中增加匿名接口规则,请求到网关时,检查请求的路径是否符合匿名接口规则,是则放行,不是则进行 token 校验,方案比较简单,只需要对网关进行处理即可。
对于一个系统来说,黑名单是最后一道关卡,所以为了安全我们需要对问题用户进行黑名单操作。
具体实现也比较简单:
用户系统是非常基础的系统,但是很多程序员工作中可能并没有真正的参与到用户系统的开发,通过此文可以对用户登录流程及配套功能有一个全面的了解。
本文链接:http://www.28at.com/showinfo-26-96762-0.html三年探索,登录注册之路仍漫漫
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
下一篇: CSS的媒体查询:响应式布局的利器