zoukankan      html  css  js  c++  java
  • 微信扫码登陆原理

    为便于理解来段非官方解释

    1、你用浏览器打开的时候,微信给你随机分配了一个链接,【相当于给你开了间房,房号1024,注意,只给你房号,没给你钥匙】,用二维码包装着,并且设置了有效时间【10分钟你不进房间,就给你取消】。这里面没有用户什么事情,所以不存在UID(user ID),只是一个随机的字母和数字组合。
    2、二维码的转码规则是统一的,所以意味着,只要是个二维码扫描软件,谁都能拿到这个链接,微信可以扫出来,我查查也可以扫出来。
    3、所以拿到链接没有用,重要的是谁拿到链接,微信拿到了,就可以从微信客户端发一条信息给服务器,告诉服务器,现在是谁使用了某个链接,其他二维码扫描软件,不能和微信服务器通话,所以毫无价值。【你拿到了房号,就给酒店老板打个电话,说是我,老板就知道张三又来开房了,其他人没有老板电话,知道房号也没用】
    4、这时候,在你刚打开的浏览器窗口里面,就知道并显示了你的信息,理论上可以直接打开聊天窗口,但是为了不突兀不尴尬,微信选择再让你在手机上做一个确认操作。【你站到你的房间门口了,老板也知道你是张三了,并且把你的那个好基友也放到了你房间里,但是谁知道你基友会在房间里干点啥?如果他正好弯腰在捡肥皂,这时候恰好你后面有人经过,房门大开大家尴尬不尴尬?所以还是老板考虑周到,他要你在电话里确认一下才给你开门,你大可以等后面没人了再开门进去】
    5、好了,现在你可以进去好好享用你的基友了。

    每打开一次微信网页版页面的时候会随机生成一个含有唯一uid的二维码,每次刷新页面都会不一样(这个可以保证一个uid只可以绑定一个账号和密码,如果一个uid可以绑定多个账号和密码,那么很可能你的电脑会登陆别人的微信哦);

     技术解答

    确实返回了唯一 id,但目的是为了识别用户身份,而且实际上打开这个页面的时候浏览器已经和 Server 创建了一个长连接等待确认信息。
    查看 的源码可以看到,这个页面在加载完毕时,也已经把很多登录后才需要的相关资源都预先加载进来了,所以长连接等待登录用户得到确认后展示用户信息的速度很快,因为无需刷页面和加载头像外的其他资源。

    2. 当用户使用登陆后的微信扫描该二维码的时候,会将这个id和手机上的微信账号及密码绑定,并上传到微信网页版服务器;

    先上个图:


    二维码样例: ,利用我查查之类的二维码应用可以得到类似这样的地址,但并不会自动打开该地址,微信客户端针对 开头的地址做了特殊处理,会自动获取相关信息并提示确认。 在手机版微信访问这个页面进行确认时,Server已经同时获得了客户端信息,并通过之前保持的长连接告知浏览器。
    3. 微信网页版页面每隔1秒或2秒会get请求该id对应的微信账号及密码,如果id绑定上了微信账号和密码,那么就可以请求到账号和密码,就可以自动登陆了。

    浏览器展示完长连接里包含的用户信息(头像等)后,会新开一个长连接等待客户端的确认操作,其 URL 类似 。从安全的角度来说,无论如何都不会让客户端获得微信帐号和密码的。要知道,密码这玩意腾讯自己都不敢保存(有兴趣的同学可以自行了解下 CSDN 明文密码泄露事件),肯定是不可能返回给浏览器的。
    而且从体感来看,怎么着都不可能是页面1-2秒轮询发起GET请求的,实际是通过堵塞等待的长连接,近乎实时的获得信息。 对于验证过程,Open API 一般是通过授权令牌(Token)来解决的,原理是当用户通过授权后,分配一个限定条件下的令牌(如限制本机访问、限制授权有效时间、限制同时登录设备数等),使获得授权的用户仅在有限的前提下能访问相关服务。 像计算机休眠后曾做的授权就自动收回了,这样就有效的避免了在别人电脑上(尤其是网吧)打开,但忘记关闭或退出这类安全问题了。
    同时,整个授权过程的验证部分在手机端进行,有效杜绝了 PC 上泛滥的各类木马、『安全工具』的监听,大大降低了帐号被盗的风险。

    所以说,核心过程应该是:浏览器获得一个临时 id,通过长连接等待客户端扫描带有此 id 的二维码后,从长连接中获得客户端上报给 server 的帐号信息进行展示。 并在客户端点击确认后,获得服务器授信的令牌,进行随后的信息交互过程。 在超时、网络断开、其他设备上登录后,此前获得的令牌或丢失、或失效,对授权过程形成有效的安全防护。

     长连接代码演示

    function _poll(_asUUID) {  
      // ....  
      $.ajax({  
        type: "GET",  
        url: "https://login." + _sBaseHost + "/cgi-bin/mmwebwx-bin/login?uuid=" + _asUUID + "&tip=" + show_tip,  
        dataType: "script",  
        cache: false,  
        timeout: _nAjaxTimeout,  
        success: function(data, textStatus, jqXHR) {  
          switch (_aoWin.code) {  
          case 200:  
            // ....  
            break;  
          case 201:  
            // ....  
            break;  
          case 408:  
            // ....  
            break;  
          case 400:  
          case 500:  
            // ....  
            break;  
          }  
        },  
        error: function(jqXHR, textStatus, errorThrown) {  
            // ....  
        }  
      });  
    }  

     
  • 相关阅读:
    HDU1712:ACboy needs your help(分组背包模板)
    HDU1203:I NEED A OFFER!(01背包)
    HDU1171:Big Event in HDU
    POJ1014:Dividing(多重背包)
    HDU2191-悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包入门)
    hdu2159FATE(二维背包)
    POJ1201 Intervals
    C++之运算符重载
    C++之强制类型转换
    MFC WinInetHttp抓取网页代码内容
  • 原文地址:https://www.cnblogs.com/yaphetsfang/p/9252909.html
Copyright © 2011-2022 走看看