关于免登录的一些实践与思考

前言

听用户说,但是不要照着做。

​ 这句话来自苏杰的《人人都是经理》这本书;在产品维度我们遵循这样的原则,其实在程序维度,也需要遵循这样的原则,如果没有意识到这一点我们也许会深陷泥潭。

案例:免登录到商品详情页面

聊一个我们之前遇到的问题,场景是这样的

  1. 用户在第三方平台登录,用户登录后点击商品会免登录到我们商城
  2. 跳转过来后,我们商城需要完成免登录操作,服务端同时给用户发放优惠券,在这个过程中必须保证通过免登录进入后同步调用登录 发券 获取商品详情接口顺序。

​ 场景就是这么简单,似乎并不是太难的问题,于是我们将我方的商品详情URL给对方,对方在URL后面拼接token,web端拿到token之后将token给后台,完成登录 发券 获取详情逻辑,流程图如下

image-20220524143533606

​ 按照我们上面的思路似乎没啥问题,无非就是用Promise控制代码顺序,但是在逻辑达到一定复杂程度后,这个问题就会变的非常棘手。

问题:非业务逻辑与业务逻辑的耦合

​ 本质上来说,从第三方平台免登陆到我们商城中,并不属于购买商品逻辑,那就不应该将其逻辑写在商品详情页中

​ 况且这必须同步,用户没有完成我们这边的登录逻辑之前,我们不能发起商品详情接口,因为我们的商品详情数据包括用户最新的优惠券信息,如果异步,就会出现用户第一次进入是没有券的情况;这样的规则就导致我们需要对商品详情页面的业务逻辑进行改动。

​ 在这样的不安中,我们修改了商品详情页面的生命周期逻辑,一旦检测到需要免登录就会先执行登录再执行商品详情的获取。

​ 后续又多次出现了其他平台免登录到商品详情页面,并且流程都不太一样,最终导致了我们的商品详情页生命周期代码凌乱不堪,异步流程难以维护,甚至会出现逻辑相互冲突的情况。

问题2:封装问题

​ 最后我们商城对接的免登录越来越多,慢慢的我们便在逻辑层面进行了封装,但是依旧还是要动具体页面生命周期代码,而有些页面比如首页就存在很多第三方平台登录进来的,在生命周期代码中就出现大量的来源判断用来调用我们封装好的免登录逻辑,并且有些第三方还是具备时效性的,虽然我们在技术层面已经尽力,但是开发起来依旧很别扭,尤其是对于频繁需要维护的模块。

解决方案

​ 再后面遇到这样一件事情,存在一个第三方商城免登录到我们的任意页面,听到需求的时候,我内心有点凌乱,因为我们目前免登录逻辑都是一对一的针对单个页面

​ 最开始我们聊了能否在nginx中进行统一拦截,后面觉得性能很差,也有种走进死胡同的感觉,后台后端同事提出一个方案,这是一个技术上微不足道,但是却非常好的解决这个问题的方案。

​ 我们将免登录的封装维度从单个逻辑的角度,提升为在对方跳转到我们目标页面中间的一层拦截

举个例子

​ 原本 www.abc.com/goods/index?token=xxxxx,我们在具体页面中处理

​ 最新 www.abc.com/autoLogin?sc=xxx&redirectUrl=www.abc.com/goods/index&token=xxxxx

如果redirectUrl存在参数一定要将该参数encodeURIComponent处理以下,以免参数解析异常

image-20220524143545282

这样做有三个优点也有一个缺点

优点一:非业务逻辑与业务逻辑的耦合的问题,将免登录代码与业务代码完美的隔离开了,不论有多少,多个性化的免登录场景,都不会影响被跳转页面的逻辑

优点二:不再需要逻辑封装,直接将与服务端交互的代码写在该页面即可,因为他已经与业务逻辑解耦合了

优点三:可以形成对接规范,降低开发对接门槛,以及出现问题的可能性。

缺点一:对于用户来说需要多跳转一层页面,有可能需要多等待20-100ms。这一点就要看取舍了,我们是单页应用,站内跳转很快,从线上效果来看对用户影响很小,几乎忽略不计。

总结

​ 回头看优化后的实现方案,其实技术难度非小,如果把需求说明白了,这是一个大学生都能写好的需求,这样一个毫无技术难度的方案,在项目中却完成让人非常头疼的部分非业务逻辑与业务逻辑的解耦合

​ 虽然作为一名开发人员,我们的本质工作就是实现需求,但是实现需求并不代表别人怎么说你就怎么做,而是根据需求加以自己的思考,在非开发角度提供自己宝贵的建议,也许,换一种思路,一个非常复杂的需求就会变得如此简单。

​ 现在让我们回到文章开头的那句话,听用户说,但是不要照着做,是不是有点感悟了。