WhatsApp Web/桌面应用程序扫描QR码的原理

57
  • 我找不到任何关于WhatsApp Web上使用的QR代码扫描的工作机制的答案。
  • 当手机(运行WhatsApp的任何智能手机)扫描浏览器上的QR代码时,认证是如何进行的。
  • 我不想了解它们背后的技术堆栈。就像WhatsApp使用修改版的xmpp,使用erlang,使用Web技术,如socket.ioajax来实现Web版本的功能。
  • 这个问题可能比较广泛。但我渴望了解背后的实现。
3个回答

114

它的工作方式如下:

1- 打开以下网址: https://web.whatsapp.com/

2- 浏览器加载页面时会加载各种JS和CSS文件,同时还会打开WebSocket(wss://w4.web.whatsapp.com/ws)- 参见此图片:

enter image description here

2.1- 每隔20000毫秒,您会在WebSocket上看到有关屏幕上QR代码刷新的通信。这是由服务器通过WebSocket(从现在开始称其为WS)发送到浏览器的。

enter image description here

2.2- 在接收到每个WS上的QR Code刷新时,您的浏览器将使用BASE64编码的GET请求获取新的QR Code。

2.3 - 请注意,服务器与浏览器之间打开的特定WS与唯一的QR代码相关联!因此,了解QR代码,服务器就知道哪个WS与其相关联!

---- 此阶段您的浏览器已经准备好使用WhatsApp应用程序,但它不知道您的ID(WhatsApp标识符,即您的手机号码),因为它无法从虚空中获取您的电话号码。

它也不需要您键入它,因为服务器不能确定该号码确实属于您。

因此,为了让服务器知道WS会话属于特定的手机,您需要使用手机进行QR阅读

3- 拿起已经经过身份验证的手机(否则您将无法访问扫描QR代码的部分),然后进行QR Code读取操作。

4- 当你的手机扫描二维码后,它会联系 WhatsApp 服务器并告知它们:

我的号码是XXXX,我的认证凭据是YYYYY,与此二维码相关联的 WS 现在可以接收我的数据了。

5- 服务器现在知道它可以将流量定向到属于该 QR Code 的特定 WS socket,并这样做!

6- 在浏览器的 WS 上,您可以看到服务器发送关于用户的数据,有关您正在进行的对话以及要获取哪些缩略图。

enter image description here

7- 浏览器从 WebSocket 获取此数据,并进行相应的 GET 请求以获取所需的缩略图和其他资源,例如用于通知的 MP3。

7.1- 浏览器上的 WS 监听器还会调用 Javascript 文件(在步骤1中接收)以使用新接口重绘页面 DOM。

8- 界面现在被重新绘制为类似 WhatsApp 应用程序的外观,并且您继续从 WS 接收数据,并在需要时发送数据,并且随着数据到达 WS,界面也会进行更新。

就是这样。

使用 Chrome 和开发人员工具,您可以实时看到所有这些内容。 您还可以查看 WS 通信(大部分内容,二进制帧需要另一个工具)并查看整个过程中发生的情况。

此外:

  • 教程的源代码Java Play 服务器


  • 但是,你的手机也需要始终连接到互联网才能使用WhatsApp Web。这种依赖关系在哪里使用?比如当你说你继续在WS上接收数据时,但如果你断开手机,你就不会在WS上接收任何数据。 - nkalra0123
    5
    没错。我只是觉得这一点与问题无关,但它相当容易理解。WhatsApp应用程序会不断向服务器发送心跳包,一种保持连接的ping消息,因此如果关闭手机,则心跳包停止,当它停止时,服务器停止向手机和WS传递数据。WS可以保持活动状态,但没有数据被接收。就是这样的机制。问题是“WhatsApp Web应用程序扫描QR码的机制”,而我描述的正是这个机制,而不是WhatsApp移动应用程序和Web应用程序的完整功能。 - SysHex
    请您详细说明第5点和第6点,关于如何在通过WebSocket获取信息后对Web浏览器进行身份验证?谢谢。 - Đức Thanh Nguyễn
    @ĐứcThanhNguyễn 我不明白你的问题。没有什么需要详细说明的。服务器创建了一个WS和一个QR码。这是一对,如果你知道QR码,你就知道与之关联的WS。如果手机拍摄了QR码并发送到服务器:“我拍摄了这个QR码的照片”,那么你就知道应该将哪个WS与该手机关联起来......因为QR码是相同的。此外,我提供了代码和完整的教程,更详细地解释了这一点。 - SysHex

    5
    它使用类似以下的内容。
    1. 用户通过 Web 浏览器打开 Whatsapp Web 应用程序。
    2. 服务器创建一个唯一的令牌(数字)并将该数字嵌入 QR 码中
    3. Whatsapp 手机应用程序读取 QR 码并解码令牌。
    4. Whatsapp 手机应用程序向 whatsapp 服务器发送有关其当前用户和这个新读取的令牌的信息。
    5. Whatsapp 服务器将令牌(+手机应用程序用户信息)与 Web 浏览器匹配。
    6. 它自动验证用户并打开一个包含他/她信息的新网页。

    例如,当每个用户打开web.whatsapp.com时,服务器会生成数千个令牌。由于HTTP是无状态的,因此服务器如何启动并找到与该特定令牌相关联的特定用户浏览器窗口。 - user6361120
    @dewnor Stack Overflow是如何区分你和我。这很类似,我们每个人都有不同的令牌。 - Atilla Ozgur
    1
    这是正确的,当用户直接与浏览器交互时(表单加载->用户输入凭据->按登录按钮->被重定向到仪表板)。但在这里,只有QR码被呈现,然后手机和服务器之间发生交互。一旦在服务器上进行身份验证,而没有任何用户与浏览器的交互,浏览器就会被重定向到仪表板。 - user6361120
    请详细说明您回答中的第5点和第6点。 - user6361120

    2
    有两种方式可以实现类似于WhatsApp的QR登录:
    1. Ajax轮询
    2. Websocket
    我已经用PHP制作了这两种方法的演示: 注意:Websocket方法需要2个端口,一个用于主应用程序,另一个用于监听Websocket连接。HTTP服务器和Websocket服务器也可以在同一端口上运行,只需要使用代理或其他方法即可。
    我还发现了一个Node.js示例:使用Node.js的QR登录Websocket

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接