1。微信PC端最早应该实现扫描二维码登录。虽然有点反人类的功能(没别的办法不扫二维码登录),但不得不说还是很爽的。下图无论是IM开发者还是普通用户,应该都不陌生:于是,搞IM产品的老板和产品经理又给程序员们增加了一个诉求——“为什么微信扫一扫登录,而我们的没有”t?”。嗯,每次IM程序员想把微信有的功能去掉,都有些困难。毕竟,老板们会理所当然地认为微信有“我的”IM产品。既然不可避免,只能老老实实理解技术原理,然后自慰,本文将简单介绍一下扫码登录功能的技术实现逻辑,实际结合淘宝和微信的扫码登录功能,学习研究技术实现思路2.基本技术原理2.1扫码登录功能到底是什么?首先介绍一下什么是二维码登录,现在大部分同学都有软件比如手机上安装的微信、QQ、淘宝。而这些应用程序都有其对应的网页。为了让用户在使用自己的网页时更方便、更安全地登录,自然而然会使用一种可以手机扫码登录的服务。几家主流厂商扫码登录的界面效果如下:很多朋友可能会觉得奇怪,网页上只显示一个二维码,怎么知道是哪个手机扫描了二维码,以及执行你在哪里登录?而且,在登录完成后,可以直接将用户信息展示给用户,这实在是太神奇了。2.2扫码登录功能的完整技术逻辑1)网页与服务端的配合逻辑:接下来就是该服务的具体实现。首先,当用户打开网站的登录页面时,会向浏览器的服务器发送获取登录二维码的请求。服务器收到请求后,随机生成一个uuid,将这个id作为key值存储在redis服务器中,并设置一个过期时间。过期后,用户登录时需要刷新重新获取二维码,同时将该键值与我司验证串结合,通过二维码生成接口生成一张二维码图片(二维码生成,网上有很多现成的接口和源码,这里不再介绍)。然后,将二维码图片和uuid返回给用户的浏览器。浏览器获取到二维码和uuid后,会每秒向浏览器发送一次是否登录成功的请求。请求中携带uuid作为当前页面的标识。这里的一些学生会感到惊讶。服务器只在redis中保存一个uuid作为键值。怎么会有用户id信息呢?这里确实会有用户id信息,是手机服务器存储在redis中的。详情请继续阅读《手机端与服务器端的协作逻辑》。2)移动端与服务端的配合逻辑:即浏览器获取二维码后,将二维码显示在网页上,并提示用户:请拿出手机,打开手机并扫描登录。用户拿出手机扫描二维码得到一个验证信息和一个uuid(扫描二维码获取字符串的功能网上也有很多demo,所以我赢了'这里详细介绍)。由于移动端已经登录,在移动端访问服务器时,参数中会包含一个用户的token,移动端服务器可以解析为用户的userId(这里取值是从token中获取的)而不是直接从移动端传递userid,为了安全,直接传递userid可能会被拦截修改,token是加密的,被修改的风险会小很多)。手机以解析后的数据和用户token为参数,向服务器发送验证登录请求(这里的服务器是手机服务器,手机服务器和web服务器不是同一个服务器)。服务器端收到请求后,首先会比对参数中的验证信息,判断是否为用户登录请求接口。如果是,则向移动终端返回确认消息。移动端收到返回后,会向用户显示登录确认框(防止用户误操作,让登录更人性化)。用户确认登录操作后,手机再次发送请求。服务端获取到uuId和userId后,将用户的userid作为值存入redis中以uuid为key的键值对中。3)登录成功的逻辑:然后,当浏览器再次发送请求时,浏览器端服务器可以得到一个用户ID,并调用登录方法生成浏览器端令牌,然后当浏览器发送请求时再次向浏览器返回用户信息,登录成功。这里之所以存储用户id而不是直接存储用户信息,是因为手机上的用户信息不一定和浏览器上的用户信息完全一样。4)详细的技术原理总结如下图:3.淘宝扫码登录技术实现本节我们以淘宝扫码登录为例,实际研究分析淘宝扫码登录的实现逻辑-扫描登录。登录接口https://login.taobao.com/member/login.jhtml返回的参数是:那么请求(GET)报文是这样的:https://qrlogin.taobao.com/qrcodelogin/qrcodeLoginCheck.do?lgToken=2c3b4d53ef0513787bf4ce711ea5ba53&defaulturl=&_ksTS=1540106757739_2804&callback=jsonp2805关键是lgToken,是网页的唯一ID。启用二维码登录后,网页正在轮询(应该是长轮询)调用接口请求服务器。扩展:吃透cookie、session、token。不扫码返回:{"code":"10001","message":"mobilescanQRCodesuccess","success":true}long如果没时间扫码,网页将停止轮询,二维码将失效!手机端确认登录时,接口返回:{"code":"10006","success":true,"url":"https://login.taobao.com/member/loginByIm.do?uid=cntaobaoxxx&token=ff82fc0d1d395a33d3b38ec5a4981336&time=1530179143250&asker=qrcodelogin&ask_version=1.0.0&defaulturl=https://www.taobao.com&webpas=0b7aed2d43f01825183e4a49c6cae47d1479929926"}表示登录成功,当然手机端与服务端在点击"确认登录"之间的交互可能就是这样:网页终端生成的lgToken用于请求服务器。服务端记住lgToken,认为已经登录,网页再次轮询请求接口时,返回真实的登录Token。然后网页就可以依赖这个Token登录了。登录。详细的技术逻辑如下图所示:4.微信扫码登录技术实现4.1技术原理流程图微信网页版访问地址为:https://wx.qq.com/,感兴趣的可以自行深入研究。4.2实际技术实现逻辑1)获取唯一uuid和包含uid信息的二维码://GetuuidgetUUID:function(){vare=t.defer();returnwindow.QRLogin={},$.ajax({url:i.API_jsLogin,dataType:"script"}).done(function(){200==window.QRLogin.code?e.resolve(window.QRLogin.uuid):e.reject(window.QRLogin.code)}).fail(function(){e.reject()}),e.promise}2)浏览器轮询服务器获取扫描状态://查看扫描状态checkLogin:function(e,a){varn=t.defer(),aa=a||0;returnwindow.code=0,window.checkLoginPromise=$.ajax({url:i.API_login+"?loginicon=true&uuid="+e+"&tip="+a+"&r="+~newDate,dataType:"script",timeout:35e3}).done(function(){newRegExp("/"+location.host+"/");if(window.redirect_uri&&window.redirect_uri.indexOf("/"+location.host+"/")<0)returnvoid(location.href=window.redirect_uri);vare={code:window.code,redirect_uri:window.redirect_uri,userAvatar:window.userAvatar};n.resolve(e)}).fail(function(){n.reject()}),n.promise}3)根据服务器返回的扫码状态如果手机没有扫码或者没有授权登录,服务器会阻塞25s左右,然后返回状态码408->前端继续轮询400二维码失败:大约5分钟不要扫里面的码,二维码无效201扫码:如果手机扫过码,服务端会立即返回状态码和用户的基本信息(window.code=201,window.code.userAvator="..."),->前端继续轮询200Authorized:如果手机点击确认登录,服务器返回200和token->前端停止轮询,获取token,重定向到目标页。具体代码示例如下://根据服务器状态返回的扫描码,执行相应的操作functiono(c){switch(c.code){case200:t.newLoginPage(c.redirect_uri).then(函数(t){varo=t.match(/