背景:
我正在尝试使用Flask-Restful和PyJWT建立基于令牌的快速身份验证的原型。我的想法是,我将拥有一个包含电子邮件和密码的表单,当用户单击“提交”时,它将生成一个令牌并将其保存在客户端浏览器中,并在以后的任何请求中使用它,直到令牌过期。
故障
在我的原型中,我能够使用JWT创建令牌,但是我不知道如何将JWT传递到后续请求中。在邮递员中进行操作时,它可以工作,因为我可以在其中指定带有令牌的Authorization标头。但是,当我通过UI登录并生成令牌时,我不知道如何通过使令牌保留在标头中直到过期而将生成的令牌传递到后续请求(/受保护的)中。当前,当我从UI登录并转到/ protected时,/ protected标头中缺少Authorization标头。
代码
class LoginAPI(Resource):
# added as /login
def get(self):
"""
renders a simple HTML with email and password in a form.
"""
headers = {'Content-Type': 'text/html'}
return make_response(render_template('login.html'), 200, headers)
def post(self):
email = request.form.get('email')
password = request.form.get('password')
# assuming the validation has passed.
payload = {
'user_id': query_user.id,
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
}
token = jwt\
.encode(payload, current_app.config['JWT_SECRET'], current_app.config['JWT_ALGORITHM'])\
.decode('utf-8')
# Is below the right way to set the token into header to be used in subsequent request?
# request.headers.authorization = token
# when {'authorization': token} below as a header, the header only shows up for /login not for any subsequent request.
return make_response({'result': 'success', 'token': token}, 200, {'authorization': token} )
class ProtectedAPI(Resource):
@check_auth
def get(self):
return jsonify({'result': 'success', 'message': 'this is a protected view.'})
# decorator to check auth and give access to /protected
def check_auth(f):
@wraps(f)
def authentication(*args, **kws):
# always get a None here.
jwt_token = request.headers.get('authorization', None)
payload = jwt.decode(jwt_token, 'secret_key', algorithms='HS512'])
# other validation below skipped.
return f(*args, **kws)
return authentication
要保留access_token
,您必须存储在客户端上,每次调用后端时都将其传递到标头中,并每次检查令牌的真实性。