Flask: before_request 检查会话和/或 Cookie 不生效
这是我的代码:
blueprint = Blueprint('client', __name__, template_folder='templates')
@blueprint.before_request
def load_session_from_cookie():
account = check_sso_cookie(request.cookies, for_view=False)
# if error occurred, return error
if 'message' in account:
session.pop('accountId', None)
return redirect(settings.LOGIN_URL)
if 'accountId' in session:
return redirect(url_for('home'))
elif 'accountId' in account:
session['accountId'] = account.get('accountId')
return redirect(url_for('home'))
else:
session.pop('accountId', None)
return redirect(settings.LOGIN_URL)
请原谅我的无知,这是我第一个使用Flask
的应用程序,涉及到会话管理。上面的代码总是返回一个错误,错误信息是RuntimeError: working outside of request context
。
以下是错误的详细信息:
Traceback (most recent call last):
File "runserver.py", line 1, in <module>
from api import app
File "/Users/dmonsewicz/dev/autoresponders/api/__init__.py", line 13, in <module>
import client
File "/Users/dmonsewicz/dev/autoresponders/api/client/__init__.py", line 33, in <module>
@blueprint.before_request(load_session_from_cookie())
File "/Users/dmonsewicz/dev/autoresponders/api/client/__init__.py", line 16, in load_session_from_cookie
account = check_sso_cookie(request.cookies, for_view=False)
File "/Users/dmonsewicz/.virtualenvs/autoresponders-api/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/dmonsewicz/.virtualenvs/autoresponders-api/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/Users/dmonsewicz/.virtualenvs/autoresponders-api/lib/python2.7/site-packages/flask/globals.py", line 20, in _lookup_req_object
raise RuntimeError('working outside of request context')
有没有其他人遇到过这个问题?
1 个回答
3
你需要注册的是函数本身,而不是函数的返回值:
blueprint.before_request(load_session_from_cookie)
注意,这里也不要加@
。这样做是把函数对象传给blueprint.before_request()
这个注册方法。
而你那种写法是先调用了load_session_from_cookie
这个函数,但在你的模块加载时,还没有请求,所以就出现了异常。
@
装饰器的写法通常是在函数定义之前,Python会自动帮你调用它:
@blueprint.before_request
def load_session_from_cookie():
# ... your function ...
注意这次我们没有直接调用它。
后面的写法是推荐的语法,只有在你不能在模块加载时使用装饰器的情况下(比如blueprint
是动态加载的,或者在一个蓝图工厂函数中等),才需要用到前面的那种写法。