【问题标题】:Flask JWT Extended cookie name overide Flask Session Cookie NameFlask JWT 扩展 cookie 名称覆盖 Flask 会话 Cookie 名称
【发布时间】:2018-07-07 02:24:09
【问题描述】:

我正在为烧瓶使用 Flask JWT 扩展扩展,并使用 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 中,因为我使用的是 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')))

那么在包含我的登录授权 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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-08-17
      • 1970-01-01
      • 2011-05-17
      • 1970-01-01
      • 2012-12-29
      • 2014-04-17
      • 2020-10-18
      • 1970-01-01
      • 2010-11-20
      相关资源
      最近更新 更多