Flask JWT 扩展 cookie 名称覆盖 Flask 会话 Cookie 名称

Flask JWT Extended cookie name overide Flask Session Cookie Name

我正在使用 Flask JWT Extended extension for flask 并使用 JWT 成功构建了一个登录应用程序。我已经在 J​​WT 扩展文档站点上使用 CSRF 保护和所有内容阅读了关于 JWT in Cookies 的教程。

我似乎无法弄清楚的是,在使用 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 调用调试 return 时,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 中,因为我使用的是 Flask 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')))

然后在包含我的登录授权的 Flask MethodView 中 POST 我有以下内容:

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

您能否提供一些代码来复制您所看到的内容?当我尝试 运行 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
...

所以我意识到我在这方面的错误。我试图从我的 auth.py 中获取要设置的 access_token_cookie 变量,它用作我的基于 RESTFUL 的微服务,我的登录应用程序调用它来进行授权。意识到从登录应用程序 POST 方法重定向回调用者后它将不可用,因为 cookie 与登录应用程序 UI 前端相关。所以我只是将访问和刷新令牌从 auth.py POST 方法返回到登录 POST 方法并让它设置 cookie,以便最终客户端可以使用它们。

与其说是代码问题,不如说是设计问题。