前言
在20年10月份,我发表了关于微信扫码实现原理的文章:《某跳动面试官:说说微信扫码登录背后的实现原理?》这篇文章发出去之后,得到不错的反馈,有不少伙伴讨论,然而当时研究的还不算深入,文章的表述也不够清晰,后续收到一位微信好友的提醒,与他讨论之后,我醍醐灌顶,由于内容几乎重构了,所以我打算重置写一份新的实现原理,在此感谢一位后端冯大佬提出的不同见解~
写作背景这个问题我是在20年8月份的时候被问到过,当时一脸懵,当跳动面试官一提出这个问题,我当场回答这个没接触过,可能不知道。面试官笑了笑:这是一个设计题,如果你原本就会的话,我就不会要你来设计了。
我:(苦笑...)凭借三寸不烂之舌和面试官讨论了起来,说完之后信心满满,但结果反手就收到了一份正式地感谢信。
当时,面试官问你还有什么想要问我的吗?我请教了这个问题,面试官回答说,你其实也猜到了一点,但是我想要的那个逻辑你没理清楚,然后吧啦吧啦引导了一下,告知可以待会学习一下,这个也挺多人讨论的。
直到11月份,又收到了一份“新”的感谢信后,我突然回想到了这个问题,想了想,这个问题不能一直丢着不管,我不去学习,当然不会自然就明白其中原理,下面我们一起来探讨一下吧。
说不定你在面跳动公司的时候也会遇到相同的问题,那么这篇文章或许能够帮助到你,请一键三连,当然,本文表述有问题的地方,欢迎读者指正,也是一个学习的过程,谢谢~
基本技术原理用户点击微信icon图标
首先,我们打开某东的网站,这里提供地址(下文打码为二维码,文章里我就尽量不显示出来了,请读者谅解)
https://passport.jd.com/new/login.aspx?
ReturnUrl=https%3A%2F%2Fwww.jd.com%2F
发现图中有一个微信登录的按钮,我们不妨点进去查看查看,与此同时我们打开控制台,查看 Network,发现有一个 302状态码,临时重定向,注意底下还有一个 location字段,这个就与我们的重定向有关。
其中,请求的 Request URL 为下述代码:
Request URL: https://qq.jd.com/new/wx/login.action?
ReturnUrl=https%3A%2F%2Fwww.jd.com%2F
Location 字段显示为如下代码(其中含有appid,后续会使用到)
Location: https://open.weixin.qq.com/connect/qrconnect?
appid=wx827225356b689e24
&state=16C44408BCCE66A99882ECB2D85A86567BAA2F274D7E27D688CE2D484A4381D35AFFAD49FD54FB2CA9C787D88B61DE8B
&redirect_uri=https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3Dd7f9f509608744c4aa64c4116896ba5f
&response_type=code
&scope=snsapi_login#wechat_redirect
那么,以上操作涉及到哪些内容呢?
首先,当我(用户)点击这个微信 icon 图标后,页面发起请求至 JD-HTTP的接口。
接口返回数据中 ,告知客户端浏览器应该跳转到哪个URL(指微信的 QrURl)以及伴随的业务参数,这个从上述 Location 字段代码可以清晰地看到。
提出疑问:点击图标后二维码是怎么出现的呢?
想必,你也会和我一样很疑惑,为啥我点击按钮了,就有二维码出现了呢?此时二维码的出现又能扯到哪些关系呢?
我们直接打开网页源代码一看究竟,我们翻到网页最底端,发现优秀的程序员给了我们注释, inline到 html 里面,给开发者工具使用。(这个后文会再此提及为什么要这样做)
那么,简单来说微信二维码图片就是一个微信的URL,当我们点击微信图标 icon之后,就会向JD服务器发起请求,然后就会返回给我们这个二维码图片的URL。
此时,我们要注意的是! 上述请求和返回与微信服务器那边还没有任何关系
浏览器轮询微信服务器
此时,就有比较帅气的观众就要问了:那到底啥时候与微信服务器有关系呢?
其实,当我们浏览器端显示出来了微信二维码之后,就开始与微信服务器有关系了,浏览器 不断请求微信服务器,用户到底同不同意登录。为了证明上述文字说明,我们看下面这张截图:
其中,我们发现了一个重要代码 wx_code,这个 code就是授权临时票据,没有这个就没有后续一系列操作。
从上述截图我们看到了 uuid不断自增,这就是 浏览器在轮询微信服务器 。
那么此时用户扫码情况:
- 1、是否扫码成功;
- 2、扫码成功后是否授权浏览器端登录JD;
- 3、页面再做相应的跳转。
注意 :2中轮询到扫码成功后,会在轮询成功的数据中,包含临时票据,供JD向自己的服务器发起请求,返回扫码者信息 OAuth2.0
注意 code 是返回到浏览器端的,浏览器拿着 code去请求JD服务器,而不是微信服务器去请求,结合下图更加清晰:
获取access_token时序图:
第二种获取code的方式
微信用户使用微信扫描二维码并且确认登录后,PC端会跳转到 https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e
为了满足网站更定制化的需求,微信文档还提供了第二种获取code的方式,支持网站将微信登录二维码内嵌到自己页面中,用户使用微信扫码授权后通过JS将code返回给网站。
上述也是某东网站的一个做法。
JS微信登录主要用途:网站希望用户在网站内就能完成登录,无需跳转到微信域下登录后再返回,提升微信登录的流畅性与成功率。网站内嵌二维码微信登录
授权流程
当用户得到 code 之后,来向微信开放平台通过code 加上 appid 和 appsecret来换取 access_token。
下述代码就是我们开头提到的,appid 后续会使用到
https://open.weixin.qq.com/connect/qrconnect?
appid=wx827225356b689e24
&state=16C44408BCCE66A99882ECB2D85A86567BAA2F274D7E27D688CE2D484A4381D35AFFAD49FD54FB2CA9C787D88B61DE8B
&redirect_uri=https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3Dd7f9f509608744c4aa64c4116896ba5f
&response_type=code
&scope=snsapi_login
在获得了 access_token 后就可以解析用户的一些基本信息,包括头像、用户名、性别、城市等。这样一来,整个微信扫描登录的过程就完成了。
更加详细的授权流程这里就不搬运了,请参考微信开发文档:网站应用登录开发指南
整个过程流程图
上篇文章 最后结尾过于仓促,很多东西没有理清楚,这次再看这张图时一下明了了许多,如果这篇文章有帮助到你增加奇怪的知识,那请麻烦你动动小指头来个一键三连吧~
本文参考- 冷血之心的博客:微信扫码登录原理解析
- 乔戈里:阿里面试官:分别说说微信和淘宝扫码登录背后的实现原理?
- 微信扫码登录的几秒钟里,到底发生了什么
- 某跳动面试官:说说微信扫码登录背后的实现原理?
- 微信开发文档:网站应用登录开发指南
- The OAuth 2.0 Authorization Framework OAuth2.0的核心角色code 扫码登录
小狮子有话说感谢以上大佬的文章,尊重劳动成果,特此提出原本链接。
我是小狮子团队的【一百个Chocolate】,全网同名,周更的前端博主,分享一些前端技术干货与程序员生活日常,欢迎各位小伙伴的持续关注,一起变优秀~
学如逆水行舟,不进则退