使用请求模块发出 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
Correct way to make a Python HTTPS request using requests module?
提问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.
当我尝试返回 的contentortext时response,我得到一个空字符串。但是,当我打印实际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 验证。那可能不是你想要的。这是文档

