【问题标题】:Correct way to make a Python HTTPS request using requests module?使用 requests 模块发出 Python HTTPS 请求的正确方法?
【发布时间】:2023-03-29 09:32:01
【问题描述】:

我必须在 Python 中发出 HTTPS 请求,并且我正在使用 requests 模块来尝试让我的生活更轻松。

请求需要有一个标头和 3 个 FORM 参数 URL 编码。这就是我正在做的事情:

header = {'Content-type': 'application/x-www-form-urlencoded', 'Authorization':'Basic ' + encoded_string, 'Connection': 'Keep-Alive', 'Host':'host.host.com'}

payload='grant_type=authorization_code&code=' + request.args['code'] + '&state=' + request.args['state'] + '&redirect_uri=http://xxx.xyz.com/request_listener'

url = 'https://serviceprovider.xxx.com/auth/j_oauth_resolve_access_code'

response = requests.post(url, data=payload, headers=header, verify=False)

当我尝试返回responsecontenttext 时,我得到一个空字符串。但是,当我打印实际的 response 对象时,它说它是 <Response [200]>,但如果这实际上是 200 OK,那么我发布的服务器也应该转到我指定的 redirect_uri,我会收到通知那里。

这没有发生,我不知道为什么。

【问题讨论】:

  • 一些尝试:使用curl 手动构造请求,以确保您知道有效请求的内容应该是什么。如果这可行,那么您就知道您在 Python 中构建或交付请求的方式存在问题。将payload 构造为字典而不是字符串。尝试构建一个准备好的请求,以便在将请求发送到服务器之前检查请求状态。

标签: python https python-requests


【解决方案1】:

您的代码正在与 Requests 库作斗争:您自己做了很多 Requests 会为您做的事情。

首先,不要自己对您的数据进行格式编码,让请求通过向data 提供字典来完成,就像@flyer 的回答所建议的那样。

当您这样做时,Requests 也会正确设置 Content-Type 标头,因此您不必这样做。另外,请不要发送Connection 标头:请求将为您管理它。这同样适用于Host 标头:发送Host 标头只会导致问题。

最后,不要自己设置 Authorization 标头,让 Requests 通过提供您的身份验证凭据来完成。惯用的请求代码是:

payload = {
    'grant_type': 'authorization_code', 
    'code': request.args['code'],
    'state': request.args['state'],
    'redirect_uri': 'http://xxx.xyz.com/request_listener',
}

url = 'https://serviceprovider.xxx.com/auth/j_oauth_resolve_access_code'

response = requests.post(url, data=payload, verify=False)

如果这不起作用,那么我会怀疑您的有效负载数据是错误的。

【讨论】:

  • 此外,OP 可能认为 Host 标头在重定向时保留,但它不是。
  • 我必须在标头中包含 base64 中的客户端 ID,所以我无法删除它,但我删除了其他所有内容。我确实将有效负载数据更改为字典,但即使请求失败,我也会收到 200 OK。我怀疑问题不在于这种情况下的请求..
  • 你怎么知道请求失败了?
【解决方案2】:

好像有两个错误。

第一个:
当你要发布数据时,数据格式应该是这样的:

payload = {
    'grant_type': 'authorization_code', 
    'code': request.args['code'],
    'state': request.args['state'],
    'redirect_uri': 'http://xxx.xyz.com/request_listener',
}

第二个:
Requests 可以自动验证 https 请求的 SSL 证书,并将verify=True 设置为默认值。您设置了verify=False,这意味着您要忽略 ssl 验证。那可能不是你想要的。这是doc

【讨论】:

  • 服务器证书存在签名问题,这就是为什么 verify 设置为 False。将有效负载更改为 dict 会导致 400 错误:它表示请求在语法上不正确。
  • @digerati32,你能提供你想要请求的完整网址吗?
猜你喜欢
  • 2013-03-12
  • 1970-01-01
  • 2016-05-17
  • 2013-05-06
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多