使用请求模块发出 Python HTTPS 请求的正确方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20485772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:34:59  来源:igfitidea点击:

Correct way to make a Python HTTPS request using requests module?

pythonhttpspython-requests

提问by digerati32

I have to make an HTTPS request in Python, and I am using the requests module to try to make my life easier.

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

The request needs to have a header and 3 FORM parameters URL encoded. This is what I am doing:

请求需要有一个标头和 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)

When I try to return the contentor textof the response, I get an empty string. However, when I print the actual responseobject, it says it is a <Response [200]>, but if this were actually a 200 OK then the server I am POSTing too should go to the redirect_uri I have specified and I would get a notification there.

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

This is not happening, and I am mystified as to why.

这不会发生,我很困惑为什么。

采纳答案by Lukasa

Your code is fighting the Requests library: you're doing a lot of stuff yourself that Requests will do for you.

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

Firstly, don't form-encode your data yourself, let Requests do it by providing a dictionary to data, like @flyer's answer suggested.

首先,不要自己对数据进行形式编码,让 Requests 通过提供字典来完成它data,就像@flyer 建议的答案一样。

When you do this, Requests will also correctly set the Content-Type header, so you don't have to. Also, please don't send a Connectionheader: Requests will manage it for you. The same applies to Hostheaders: sending a Hostheader can only cause problems.

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

Finally, don't set the Authorization header yourself, let Requests do it by providing it with your authentication credentials. The idiomatic Requests code would be:

最后,不要自己设置 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)

If that doesn't work, then I would suspect your payload data is bad.

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

回答by flyer

It seems that there are two mistakes.

好像有两个错误。

The first one:
When you want to post data, the data format should be like this:

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

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

The second:
Requestscould verify SSL certificates for https requests automatically and it sets verify=Trueas default. You set verify=Falseand that means that you want to ignore the ssl verification. That maybe not what you want. Here is the doc

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