[英]How to implement login required decorator in Flask
我有 2 个协同工作的 Flask 应用程序(不同的项目)。 一个实现了一些使用令牌进行身份验证的 API。 第二个使用 API 并为其创建一个 Web 界面。 现在我有一个登录功能,可以将用户名和密码发送到 API,如果正确,则获取身份验证令牌作为回报。 获得令牌后,我将其保存到用户的会话中,现在应将用户视为已登录/已验证。 对于这种情况,我该如何实现 login_required 装饰器。
这是我的登录功能 -
def login(self):
response = make_request(BASE_URL + 'login/', clean_data(self.data))
if response.status_code == 200:
session['auth_token'] = response.json().get('auth_token')
return True
return False
如何制作 login_required 装饰器?
如果重要的话,我还使用 Redis 来存储会话。
查看有关装饰器的官方烧瓶文档: https ://flask.palletsprojects.com/en/1.1.x/patterns/viewdecorators/ 或 python 文档https://www.python.org/dev/peps/pep -0318/还有。
您的装饰器应该类似于:
from functools import wraps
from flask import abort
import jwt
def authorize(f):
@wraps(f)
def decorated_function(*args, **kws):
if not 'Authorization' in request.headers:
abort(401)
user = None
data = request.headers['Authorization'].encode('ascii','ignore')
token = str.replace(str(data), 'Bearer ','')
try:
user = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])['sub']
except:
abort(401)
return f(user, *args, **kws)
return decorated_function
...然后在你的 app.py 中你可能有:
@app.route('/api/game', methods=['POST'])
@authorize
def create(user):
data = json.loads(request.data)
....
在这种特殊情况下,我使用 JWT 作为令牌,您的令牌可以分别不同,令牌的解码可以是您的自定义实现,但基本机制与上面的示例非常相似。
我会将以下装饰器函数放在常见的地方
def validate_api_token(validation_func):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kws):
api_token = request.headers.get('Authorization')
is_valid_api_token = validation_func(api_token)
if is_valid_api_token:
return f(*args, **kws)
return 'Invalid API Token', 401
return decorated_function
return decorator
对于小型 POC flask 应用程序,如果您可以将令牌存储在非版本控制文件中,则可以使用以下方法:
# tokens are read from a non-versioned `.tokens` file and loaded into a set
api_tokens = load_api_tokens()
def simple_api_token_validation(api_token):
return api_token in api_tokens
@app.route("/v1/my/secret/function", methods=['POST'])
@validate_api_token(simple_api_token_validation)
def my_secret_function():
body = request.get_json()
# ...
另一个简单的选择是查询数据库(例如 redis):
redis_session = Redis(host=REDIS_HOST, password=REDIS_PASSWORD)
def redis_api_token_validation(api_token):
if not api_token:
return False
api_token_hash = hashlib.sha256(api_token.encode()).hexdigest()
return redis_session.exists(f'api:tokens:{api_token_hash}')
@app.route("/v1/my/secret/function", methods=['POST'])
@validate_api_token(redis_api_token_validation)
def my_secret_function():
body = request.get_json()
# ...
@Velin 回答的最佳 IMO 是使用 jwt 来验证令牌
鉴于每个后续请求都将包含 API 令牌,装饰器应执行以下操作
有关装饰器的解释,请查看此链接: http ://thecodeship.com/patterns/guide-to-python-function-decorators/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.