2

我正在为烧瓶使用 Flask JWT 扩展扩展,并使用 JWT 成功构建了一个登录应用程序。我已经使用 CSRF 保护和所有内容在 JWT 扩展文档站点上的Cookies 中浏览了有关 JWT的教程。

我似乎无法弄清楚的是,当使用 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 中,因为我使用的是 Flaskconfig.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 中,我有以下内容:

授权文件

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
4

2 回答 2

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
...
于 2018-07-07T03:51:37.533 回答
0

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

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

于 2018-07-11T03:37:02.183 回答