美文网首页
微信扫码登录技术实现的简单思考

微信扫码登录技术实现的简单思考

作者: 朱季谦 | 来源:发表于2022-10-14 18:23 被阅读0次

    原创/朱季谦

    微信扫码登录是经常用到的的骚操作,但是,其实现的思路是怎样的,可能很多人都没有去思考过。记得曾经在一次面试当中,面试官就曾问过微信扫码登录的实现思路,这次,以微信读书网页版扫码登录为例子,聊聊我对微信扫码登录技术实现思路一些思考。

    以谷歌浏览器来做本次分析,打开F12,准备随时观察http连接状况。

    接下来用谷歌浏览器打开网页版微信读书,点击登录,会弹出一个二维码。

    可以看到,在二维码弹出来的时候,前端调用了后端两个接口,一个是getuid(),一个是getinfo(),这里面涉及到哪些逻辑实现呢?


    image.png

    稍微思考一下,其实很好理解,每个随机生成的二维码,其实都是一个uuid码,也就是说,在点击登录的时候,会执行一个getuid()方法,去调用后端API:web/login/getuid,然后返回一个随机生成的uuid码。当这个uuid码返回到前端上时,就会以二维码的形式展示。根据uuid如何生成二维码,我后面再写一篇小白文来分析下。

    在谷歌浏览器F12调出的控制台页面,点击getuid(),在右边栏的Preview框里,可看到该方法返回一个随机生成的uuid:38e673a9-5bd3-4f0c-ba2f-62ab376372a9

    image.png

    返回uuid的同时,还调用了另一个getinfo()方法——可见,这应该是getuid调用成功后的回调方法,也就是当getuid()执行成功后,在得到一个uid时,就立马调用getinfo()方法,同时将生成的uid当做参数传给getinfo(),让其去访问后端API。

    image.png

    当没有用手机微信进行扫码操作时,会看到getinfo()一直没有返回值,这时,它传给后端的uuid正在做轮询查询操作,在某段时间内,若没有轮询成功,就会断开连接,接口调用失败。

    image.png

    到这里,可以简单归纳下网页版微信登录页面生成二维码的流程,即,在点击登录按钮时,代码层面会执行getuid()方法去调用后端API接口。

    下面用两段伪代码来说明下大概代码逻辑:

    一.前端React获取uuid并回调给getinfo()伪代码:

      1 export const getuid=(params={},queue='getuid')=>dispatch=>{
      2     http.post({
      3         url:'https://weread.qq.com/web/login/getuid',
      4         params:params,
      5         queue:queue,
      6         callback:(res)=>{
      7             //getuid方法执行成功,返回{uid: "38e673a9-5bd3-4f0c-ba2f-62ab376372a9"},
                  //回调执行getinfo()
      8             dispatch(getinfo({uid:res.uid}))
      9         }
     10     });
     11 }
     12 
     13 export const getinfo=(params={},queue='getinfo')=>dispatch=>{
     14     http.get({
     15         url:'https://weread.qq.com/web/login/getinfo',
     16         params:params,
     17         queue:queue,
     18         callback:(res)=>{
     19          //若登录成功,应该重定向到已登录状态的主页
     20         }
     21     });
     22 }
    复制代码
    

    二.后端API接口/web/login/getinfo伪代码:

      1 public String getinfo(String uid){
      2     ......
      3         //循环查询uid在redis里是否存在值
      4         while(true){
      5             String user=redisTemplate.opsForValue().get(uid);
      6             if(user!=null){
      7                 return user;
      8             }
      9         }
     10     ......
     11 }
    复制代码
    

    用一个时序图来简单表示这个过程:

    image.png

    那么,什么时候才能通过uid去redis查询才能得到返回值呢?

    这时候,就要说到扫码阶段了

    当getinfo(String uid)接口在轮询查询redis是否有key为uid的值时,用户拿出手机,在二维码有效时间内,用微信扫一扫进行扫码操作,这时,手机上就会出现该页面展示:


    image.png

    若点击登录,网页版微信读书就会刷新,进入到已登录状态的首页。

    这个过程很好理解,即在扫码后,手机端会从二维码中获取到uid,这时,若点登录,就会将uid与微信用户信息一块包装成json格式post提交给后端,然后在后端接口中,将以uid:user的key-value形式set插入到redis数据库。这时,另一边正在以uid当做key值轮询去redis是否有值的getinfo(String uid)方法,通过类似redisTemplate.opsForValue().get(uid)的方式,正好就能通过uid把刚插入redis的user信息查询出来,最后返回给PC端的微信读书前端,即登录成功。

    最后,完整的流程可以时序图这样表示:

    image.png

    PC端微信读书登录成功的时候,页面重新做了刷新,应该是在后台做了接口重定向,具体如何重定向,感兴趣的朋友可以自行思考研究,微信扫码登录大体上就是这个思路,但细节方面应该会有更多相关校验在里面。

    这里主要是分析下它的整体实现思路。

    值得提一点是,PC端微信读书前端其实做了反调试,但没关系,它这个反调试的做法很容易破解,可参考我的做法,即打开谷歌浏览器,按F12,调出控制台,把这个图标点亮,就可以关闭微信读书前端自带的反调试设置了。

    image.png

    相关文章

      网友评论

          本文标题:微信扫码登录技术实现的简单思考

          本文链接:https://www.haomeiwen.com/subject/gzqkzrtx.html