Flask JWT扩展cookie名称覆盖Flask Session Cookie名称

时间:2018-07-07 02:24:10

标签: python-3.x flask flask-jwt-extended

我正在使用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

2 个答案:

答案 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,以便最终客户端可以使用它们。

这更多是设计问题,而不是代码问题。