我正在编写Flask后端,以通过JWT进行身份验证以提供RESTful API。
我正在使用Flask-Admin进行管理,为了使用一种身份验证方法,我也想对其使用JWT身份验证。
我在Flask-Admin中添加了一个简单的登录表单,用于在cookie中设置JWT令牌。
在我的create_form
的{{1}}方法中的请求中找到并正确解码了JWT令牌,但是在发布表单时(通过单击我的创建表单的sqla.ModelView
按钮) ,出现401错误:“标头中缺少CSRF令牌。
有人可以帮忙吗?
登录路线
save
烧瓶管理视图
@bp_api.route('/api/user/login', methods=('POST',))
def login():
data = request.json
web = request.args.get('web', 0, type=int)
user = User.query.filter(User.username==data['username']).first()
if not user:
return jsonify({'msg': 'User {} doesn\'t exist'.format(data['username'])}), 400
if not user.confirmed_on:
return jsonify({'msg': f'{user.email} not confirmed'}), 400
if check_password_hash(user.password, data['password']):
access_token = create_access_token(identity = data['username'], fresh=True)
refresh_token = create_refresh_token(identity = data['username'])
if web:
resp = jsonify({'username': f'{user.username}'})
set_access_cookies(resp, access_token)
set_refresh_cookies(resp, refresh_token)
else:
resp = jsonify({'msg':f'Logged as {user.username}',
'access_token': access_token, 'refresh_token': refresh_token}
)
return resp, 200
else:
return jsonify({'msg': 'Invalid password.'}), 401
日志
from flask_admin.base import BaseView
from flask_admin.contrib import sqla
from flask_jwt_extended import (
get_current_user,
get_jwt_identity,
jwt_required,
verify_jwt_in_request,
verify_jwt_refresh_token_in_request,
create_access_token,
set_access_cookies,
unset_jwt_cookies,
)
from flask_jwt_extended.exceptions import NoAuthorizationError
from jwt import ExpiredSignatureError
class PhaunosBaseView(BaseView):
def render(self, template, **kwargs):
try:
verify_jwt_in_request()
self._template_args['current_user'] = get_current_user()
current_app.logger.info("Access token ok for user {}".format(get_current_user()))
resp = make_response(super(PhaunosBaseView, self).render(template, **kwargs))
except ExpiredSignatureError:
# if the access token has expired, create new non-fresh token
current_app.logger.info("Access token has expired.")
try:
verify_jwt_refresh_token_in_request()
self._template_args['current_user'] = get_current_user()
access_token = create_access_token(identity=get_jwt_identity(), fresh=False)
resp = make_response(super(PhaunosBaseView, self).render(template, **kwargs))
set_access_cookies(resp, access_token)
except ExpiredSignatureError:
# if the refresh token has expired, user must login again
current_app.logger.info("Refresh token has expired")
resp = make_response(super(PhaunosBaseView, self).render(template, **kwargs))
unset_jwt_cookies(resp)
except NoAuthorizationError:
current_app.logger.info("No authorization token.")
resp = make_response(super(PhaunosBaseView, self).render(template, **kwargs))
return resp
class PhaunosModelView(PhaunosBaseView, sqla.ModelView):
pass
class ProjectAdminView(PhaunosModelView):
def create_form(self, obj=None):
current_app.logger.info("In create_form")
form = super(ProjectAdminView, self).create_form(obj)
current_app.logger.info(request.headers)
verify_jwt_in_request()
return form
def on_model_change(self, form, model, is_created):
current_app.logger.info("In on_model_change")
current_app.logger.info(id(request))
current_app.logger.info(request.headers)
verify_jwt_in_request()
# then set get_current_user() to some model attribute