强制 Content-Type 或在 Flask 中公开 request.data 以获得已知的内容类型
我正在 Python/Flask 中重新创建服务,但遇到了现有客户端身份验证方式的问题。出于兼容性原因,我必须匹配现有的客户端方案。
现有的客户端获取用户名、密码并对其进行 Base64 编码。尽管听起来很相似,但这不是 HTTP 基本身份验证。下面是一些创建此登录请求的示例代码。
credentials = {
'username': '[email protected]',
'password': 'password'
}
data = b64encode(urlencode(credentials))
request = urllib2.Request(loginURL)
request.add_data(data)
# request.add_header('Content-Type', 'application/gooblygop')
# 'application/x-www-form-urlencoded' seems to be a default Content-Type
login = urllib2.urlopen(request)
在服务器端,我获取 POST 数据并对其进行 base64 解码,以再次获取用户名和密码信息。
flask server:
@app.route('/login', methods=['POST'])
def login():
error = None
if request.method == 'POST':
# post data: cGFzc3dvcmQ9ZGVmYXVsdCZlbWFpbD10ZXN0JTQwZXhhbXBsZS5jb20=
data = b64decode(request.data)
# decoded data: password=default&email=test%40example.com
return('ok')
问题在于内容类型。如果我在客户端 (application/gooblygop) 中指定未知的 Content-Type,Flask 会将 POST 数据公开到 request.data,并且我可以解码 base64 字符串。如果我将 Content-Type 保留为默认值 (application/x-www-form-urlencoded),则原始数据不会暴露给 request.data,并且我不知道如何检索 base64 编码的字符串并使用它。
现有的客户端软件几乎都默认为 x-www-form-urlencoded,但我不能相信情况总是如此。
本质上,我需要一种可靠的服务器端方法来访问该编码字符串,无论客户端程序声明什么内容类型。
其他说明: 我对 Python 非常陌生,有 PHP 背景。所以我非常愿意接受建议。此外,该项目主要供个人使用。
I am recreating a service in Python/Flask and am running into an issue with the way the existing clients authenticate. I have to match the existing clients scheme for compatibility reasons.
The existing clients take the username, password and base64 encode it. This is not HTTP Basic Authentication, despite sounding similar. Below is some sample code that would create this login request.
credentials = {
'username': '[email protected]',
'password': 'password'
}
data = b64encode(urlencode(credentials))
request = urllib2.Request(loginURL)
request.add_data(data)
# request.add_header('Content-Type', 'application/gooblygop')
# 'application/x-www-form-urlencoded' seems to be a default Content-Type
login = urllib2.urlopen(request)
On the server side, I take the POST data and base64 decode it to get the username and password information again.
flask server:
@app.route('/login', methods=['POST'])
def login():
error = None
if request.method == 'POST':
# post data: cGFzc3dvcmQ9ZGVmYXVsdCZlbWFpbD10ZXN0JTQwZXhhbXBsZS5jb20=
data = b64decode(request.data)
# decoded data: password=default&email=test%40example.com
return('ok')
The problem is the Content Type. If I specify an unknown Content-Type in the client (application/gooblygop), Flask exposes the POST data to request.data and I can decode the base64 string. If I leave the Content-Type as default (application/x-www-form-urlencoded), the raw data is not exposed to request.data and I don't know how to retrieve the base64 encoded string and make use of it.
The existing client software all pretty much defaults to x-www-form-urlencoded, but I can't rely on that always being the case.
Essentially, I need a reliable, server-side method for accessing that encoded string no matter what Content-Type the client program states.
Other notes: I am very new to Python, coming from a PHP background. So I am very open to suggestions. Also, this project is primarily for personal use.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在处理具有普通 mime 类型的 urlencoded 帖子时,您需要查看
request.form
对象。在这种情况下,您有一个不寻常的表单,但这里有一个方法:您可能想要修改登录位来检查 mimetype,这是一个对当前设置进行最小更改的版本:
这是第一个的输出代码示例,有两个请求:
You want to look at the
request.form
object when dealing with urlencoded posts with normal mimetypes. In this case you have an unusual form, but here is a way to do it:You probably want to modify the login bit to check the mimetype, here is a version with minimal changes to your current setup:
This is the output of the first code sample, with two requests:
您是否考虑过使用 json 在 POST 中传递数据? Flask 内置了对传递 json 数据的支持。另外,如果你将 headers 中的 Content-Type 设置为 application/json 那么 Flask 会自动为你 dejson POST 数据并将其放入 request.json
这是请求的应用程序
这是 Flask 视图
我建议你使用curl进行测试如果您使用的是 Linux 终端,也是如此。这是一个例子
Have you thought about using json to pass your data in the POST? Flask has built in support for passing json data. In addition, if you set the Content-Type in the headers to application/json then flask will automatically dejson the POST data for you and put it in request.json
Here is the requesting application
This is the Flask view
I suggest you test using curl as well if you are using the linux terminal. Here is an example