我正在使用Flask的Flask JWT Extended扩展,并已成功使用JWT构建了登录应用程序。我在JWT扩展文档站点上的JWT in Cookies上使用CSRF保护和所有内容来完成了该教程。
我似乎无法弄清楚的是,当使用set_access_cookies()和set_refresh_cookies()方法时,JWT并未保存在使用JWT扩展默认配置设置命名的httponly cookie中。
app.config.setdefault('JWT_ACCESS_COOKIE_NAME', 'access_token_cookie')
app.config.setdefault('JWT_REFRESH_COOKIE_NAME', 'refresh_token_cookie')
相反,当我调试从auth调用返回的内容时,cookie会保存在基本Flask默认配置中。
'SESSION_COOKIE_NAME': 'session',
只要确保在JWTManager()中注册我的应用程序,set_access_cookies()和set_refresh_cookies()方法是否会覆盖Flask的默认默认配置?
uscc_login_app = Flask(__name__)
jwt = JWTManager(uscc_login_app)
或者在Flask JWT扩展基础文档中还有其他我想念的内容,以确保在适当时使用其默认配置吗?
根据请求更新了代码。
代码非常分散,但这是我最好的选择,其中包括我认为会有所帮助的内容。
在 init.py 中:
from flask import Flask, url_for
from flask_restful import Api
from flask_jwt_extended import JWTManager
from resources.auth import Authenticate
from resources.refresh import Refresh
from temp_app.temp import TempApp
from uscc_login.uscc_app_login import *
uscc_login_app = Flask(__name__)
uscc_login_app.config.from_object(os.environ.get('FLASK_ENV'))
jwt = JWTManager(uscc_login_app)
api = Api(uscc_login_app, prefix='/v1')
# Add resources via the add_resource method
api.add_resource(Authenticate, '/login')
api.add_resource(Refresh, '/refresh_token')
login_view = Login.as_view(name='uscc_login')
uscc_login_app.add_url_rule('/login', view_func=login_view, methods=['POST', 'GET'])
在我的app.py中:
from uscc_login import uscc_login_app
if __name__ == '__main__':
uscc_login_app.run(debug=uscc_login_app.config.get('DEBUG'), threaded=uscc_login_app.config.get('THREADED'),
port=uscc_login_app.config.get('PORT'), host=uscc_login_app.config.get('HOST'))
在我的config.py中,因为我使用的是烧瓶config.from_objects
import os
import datetime
uscc_login_app_dir = os.path.abspath(os.path.dirname(__file__))
class BaseConfig:
SECRET_KEY = os.environ.get('USCC_SECRET_KEY') or 'you-will-never-guess'
JWT_SECRET_KEY = os.environ.get('USCC_JWT_KEY') or 'super-secret'
JWT_TOKEN_LOCATION = ['cookies']
JWT_COOKIE_CSRF_PROTECT = True
JWT_HEADER_TYPE = 'JWT'
PROPAGATE_EXCEPTIONS = True
THREADED = True
class DevelopmentConfig(BaseConfig):
DEBUG = True
PORT = 5000 if os.environ.get("PORT") is None else int(os.environ.get("PORT"))
HOST = os.environ.get('HOST') or 'localhost'
if os.environ.get('access_token_expiration') is not None:
JWT_ACCESS_TOKEN_EXPIRES = datetime.timedelta(seconds=int(os.environ.get('access_token_expiration')))
if os.environ.get('refresh_token_expiration') is not None:
JWT_REFRESH_TOKEN_EXPIRES = datetime.timedelta(seconds=int(os.environ.get('refresh_token_expiration')))
因此,在包含登录授权POST的Flask MethodView中,我具有以下内容:
auth.py
import sys
import os
from flask import jsonify, request
from flask_restful import Resource
from flask_jwt_extended import create_access_token, create_refresh_token, jwt_refresh_token_required, get_jwt_identity, \
set_access_cookies, set_refresh_cookies
from utilities import Common
class Authenticate(Resource):
@staticmethod
def post():
"""
:return:
"""
api_cred_path = os.environ.get('api_cred_path')
if api_cred_path is None:
response = jsonify({"msg": "Environment Variable 'api_cred_path' is not set."})
response.status_code = 500
return response
if not request.is_json:
response = jsonify({'msg': 'Missing JSON in request'})
response.status_code = 400
return response
params = request.get_json()
user_name = params.get('username')
user_password = params.get('password')
if not user_name:
response = jsonify({'msg': 'Missing username parameter'})
response.status_code = 400
return response
if not user_password:
response = jsonify({'msg': 'Missing password parameter'})
response.status_code = 400
return response
if Common.check_path_exists(api_cred_path):
with open(api_cred_path) as afh:
for line in afh:
file_userid, file_password = line.split('=')
if file_userid == user_name and file_password.strip('\n') == user_password:
access_token = create_access_token(identity=user_name)
refresh_token = create_refresh_token(identity=user_name)
response = jsonify({'login': True})
set_access_cookies(response, access_token)
set_refresh_cookies(response, refresh_token)
# # Identity can be any data that is json serializable
# art = {
# 'access_token': create_access_token(identity=user_name),
# 'refresh_token': create_refresh_token(identity=user_name)}
# response = jsonify(art)
response.status_code = 200
return response
else:
response = jsonify({"msg": "api_cred_path invalid."})
response.status_code = 500
return response
response = jsonify({'msg': 'Bad username or password'})
response.status_code = 401
return response
答案 0 :(得分:0)
您能否提供一些代码来复制您所看到的内容?当我尝试在jwt代码(https://github.com/vimalloc/flask-jwt-extended/blob/master/examples/jwt_in_cookie.py)中运行示例令牌时,登录时会看到预期的cookie值:
$ http :5000/token/auth username=test password=test
...
Set-Cookie: access_token_cookie=<jwt>; HttpOnly; Path=/api/
Set-Cookie: refresh_token_cookie=<jwt>; HttpOnly; Path=/token/refresh
...
答案 1 :(得分:0)
所以我意识到了我的错误。我试图从auth.py设置access_token_cookie变量,该变量用作我的基于RESTFUL的微服务,我的登录应用程序调用该微服务来进行授权。从Cookie到登录应用程序UI前端相关后,从登录应用程序POST方法重定向回调用者后,意识到它将不可用。因此,我只是将访问和刷新令牌从auth.py POST方法返回到登录POST方法,并让它设置cookie,以便最终客户端可以使用它们。
这更多是设计问题,而不是代码问题。