需求
一般我们使用Flask进行前后端分离开发的时候,前端与后端直接就是通过 API 请求进行数据交互,那么我们可以如何去确认我们的服务是安全的呢?
如果是前后端不分离的单体应用中,用户登陆一般是通过填写页面表单,并且在页面配置 csrftoken 来保证该页面为服务页面,然后登陆成功之后,将用户的登陆状态保存在服务器的session中,然后session_id 以 cookie 存储在浏览器端。
在前后端分离的开发中,我们一般会基于 REST 的规则设计 API,而单纯的 HTTP 请求是无状态的,要求浏览器客户端在每一次请求都要提供认证的信息,那么怎么去便利地让 HTTP 提供认证呢?
HTTP 协议提供了两种认证机制:Basic 和 Digest。
而在 Flask 框架中,有一个库Flask-HTTPAuth
可以让我们很方便实现这两个认证功能,下面来示例演示一下。
安装 Flask-HTTPAuth
Github地址:https://github.com/miguelgrinberg/Flask-HTTPAuth
使用 pip 库安装:
pip install Flask-HTTPAuth
Basic authentication 基础认证示例
示例代码
from flask import Flask, jsonify, make_response
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
auth = HTTPBasicAuth()
# 用户的名称以及密码
users = {
"john": generate_password_hash("hello"),
"susan": generate_password_hash("bye")
}
@auth.verify_password
def verify_password(username, password):
if username in users and check_password_hash(users.get(username), password):
return username
@app.route('/')
@auth.login_required
def index():
return "Hello, %s!" % auth.current_user()
# 自定义未认证通过的返回
@auth.error_handler
def unauthorized():
# return make_response(jsonify({'error': 'Unauthorized access'}), 401)
return make_response(jsonify({'error': 'Unauthorized access'}), 403) # 403 禁止
if __name__ == '__main__':
app.run()
启动服务后,使用POSTMAN测试如下:
-
认证成功

-
认证失败

使用 Curl 的方式测试如下:
-
认证成功
[root@dev ~]# curl -u john:hello -i http://127.0.0.1:5000/
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 12
Server: Werkzeug/1.0.1 Python/3.7.1
Date: Fri, 18 Sep 2020 07:34:14 GMT
Hello, john![root@dev ~]# -
认证失败
[root@dev ~]# curl -u jo:hello -i http://127.0.0.1:5000/
HTTP/1.0 403 FORBIDDEN
Content-Type: application/json
Content-Length: 32
WWW-Authenticate: Basic realm="Authentication Required"
Server: Werkzeug/1.0.1 Python/3.7.1
Date: Fri, 18 Sep 2020 07:34:42 GMT
{"error":"Unauthorized access"}
[root@dev ~]#
Digest authentication 摘要认证示例
示例代码
from flask import Flask, jsonify, make_response
from flask_httpauth import HTTPDigestAuth
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth()
users = {
"john": "hello",
"susan": "bye"
}
@auth.get_password
def get_pw(username):
if username in users:
return users.get(username)
return None
@app.route('/')
@auth.login_required
def index():
return "Hello, %s!" % auth.username()
# 自定义未认证通过的返回
@auth.error_handler
def unauthorized():
# return make_response(jsonify({'error': 'Unauthorized access'}), 401)
return make_response(jsonify({'error': 'Unauthorized access'}), 403) # 403 禁止
if __name__ == '__main__':
app.run(host="0.0.0.0", port="5000", debug=True)
启动服务后,使用POSTMAN测试如下:
-
认证成功

-
认证失败

原文始发于微信公众号(海洋的渔夫):33. Flask实现BasicAuth基础认证以及DigestAuth摘要认证
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/31036.html