首页 > 解决方案 > python vs nodejs的https实现有什么不同?

问题描述

我试图找出一个奇怪的问题。我有工作 python 代码,我想将其转换为 NodeJS。Python代码非常简单并且有效:

import requests

LOGIN_URL = 'https://android.clients.google.com/auth'
params = {'Email': '***', 'EncryptedPasswd': b'***', 'service': 'androidmarket', 'accountType': 'HOSTED_OR_GOOGLE', 'has_permission': 1, 'source': 'android', 'device_country': 'us', 'lang': 'us'}
response = requests.post(LOGIN_URL, data=params, verify=True)
print(response.text)

这是 NodeJS 版本代码:

const request = require('request');

const LOGIN_URL = 'https://android.clients.google.com/auth'
const params = {'Email': '***', 'EncryptedPasswd': '***', 'service': 'androidmarket', 'accountType': 'HOSTED_OR_GOOGLE', 'has_permission': 1, 'source': 'android', 'device_country': 'us', 'lang': 'us'}
request({url: LOGIN_URL, method: 'POST', form: params}, function(error, response) {
   console.log(response.statusCode);
});

这不起作用,我正在返回 403 - 错误请求。我试图将协议更改为 http,然后在 Wireshark 中检查数据包内容。它们几乎相同,只是略有不同。我尝试通过覆盖 NodeJS 版本中的标头来消除所有差异,但没有帮助。所以我的猜测是https有问题吗?

我错过了什么?Python 和 NodeJS 之间可能有什么区别?

标签: pythonnode.jshttp

解决方案


第二种猜测:

登录需要 cookie,NodeJSrequests默认禁用 cookie。尝试:

const request = request.defaults({jar: true})

第一个猜测:

发布的 python 代码和 Node.js 代码之间的差异:

  • python 代码发送这些标头:
HTTP_ACCEPT: */*
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_CONNECTION: keep-alive
HTTP_USER_AGENT: python-requests/2.24.0
  • 节点代码仅发送以下标头:
HTTP_CONNECTION: close

很可能标头可能是问题所在,但也可能是 Python 代码可以访问 cookie jar 并且正在将 cookie 添加到 Node.JS 代码所没有的请求中。

另一种可能性是您的两个客户端正在使用两个不同的 TLS 堆栈(或至少 2 个不同的配置),并且 NodeJS 客户端无法协商可接受的密码。

我建议您使用 Postman 之类的工具手动尝试请求的变体,以确定哪些有效,哪些无效。如果你让它在 Postman 中工作,使用 Postman 导出 Python 和 NodeJS 的代码片段并确认它们工作。如果导出的代码在 Python 而不是 NodeJS 中工作,那么问题不在于代码。

问题很可能是您没有意识到的,因此没有告诉我们。也有 Postman 导出curlwget命令,因此您可以验证它们是否在您的 Docker 容器中工作,并且问题不在于容器或 Docker 网络。用于curl -v查看正在协商的 TLS 密码并将 NodeJS 配置为仅使用该版本的 TLS 和仅使用该密码,因为 Google 喜欢阻止允许降级到旧的损坏 TLS 版本或弱密码的客户端。


推荐阅读