管理登录的最佳方式是通过json web token(JWT)。通过使用 JWT,您无需保存任何令牌,因为您可以通过推断令牌的内容来获取管理用户所需的所有信息。
要使用flask 执行此操作,您可以使用Flask-JWT 库,它实现了管理JWT 所需的所有功能,或者Flask-JWT-Extended。
Flask-JWT-Extended 与 Flask-JWT 非常相似,但具有更多的配置选项和更多的功能。例如,它允许令牌刷新。
工作流程应如下所示:
- 用户通过适当的 rest 调用登录,如果凭据正确,则创建 JWT 并将其返回给客户端,客户端负责将其保存在本地并在后续调用中重复使用
- 对于所有需要身份验证的后续调用,客户端将负责在 HTTP 请求标头中指定 JWT
- 接收调用的服务器 rest 负责推断令牌的内容(验证它是否有效)以获取必要的信息。
示例取自Flask-JWT-Extended Basic Usage:
from flask import Flask
from flask import jsonify
from flask import request
from flask_jwt_extended import create_access_token
from flask_jwt_extended import get_jwt_identity
from flask_jwt_extended import jwt_required
from flask_jwt_extended import JWTManager
app = Flask(__name__)
# Setup the Flask-JWT-Extended extension
app.config["JWT_SECRET_KEY"] = "super-secret" # Change this!
jwt = JWTManager(app)
# Create a route to authenticate your users and return JWTs. The
# create_access_token() function is used to actually generate the JWT.
@app.route("/login", methods=["POST"])
def login():
username = request.json.get("username", None)
password = request.json.get("password", None)
if username != "test" or password != "test":
return jsonify({"msg": "Bad username or password"}), 401
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token)
# Protect a route with jwt_required, which will kick out requests
# without a valid JWT present.
@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
# Access the identity of the current user with get_jwt_identity
current_user = get_jwt_identity()
return jsonify(logged_in_as=current_user), 200
if __name__ == "__main__":
app.run()
HTTP 调用以进行身份验证:
$ http POST :5000/login username=test password=test
HTTP/1.0 200 OK
Content-Length: 288
Content-Type: application/json
Date: Sun, 24 Jan 2021 18:10:39 GMT
Server: Werkzeug/1.0.1 Python/3.8.6
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTYxMTUxMTgzOSwianRpIjoiMmI0NzliNTQtYTI0OS00ZDNjLWE4NjItZGVkZGIzODljNmVlIiwibmJmIjoxNjExNTExODM5LCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoidGVzdCIsImV4cCI6MTYxNDEwMzgzOX0.UpTueBRwNLK8e-06-oo5Y_9eWbaN5T3IHwKsy6Jauaw"
}
使用受保护端点的 HTTP 调用:
http GET :5000/protected Authorization:"Bearer <access_token>"
HTTP/1.0 200 OK
Content-Length: 24
Content-Type: application/json
Date: Sun, 24 Jan 2021 18:12:02 GMT
Server: Werkzeug/1.0.1 Python/3.8.6
{
"logged_in_as": "test"
}