英文:
How can I make tornado web return 403 if current_user is None instead of redirect to login_url?
问题
以下是方法authenticated的实现:
def authenticated(
method: Callable[..., Optional[Awaitable[None]]]
) -> Callable[..., Optional[Awaitable[None]]]:
"""Decorate methods with this to require that the user be logged in.
If the user is not logged in, they will be redirected to the configured
`login url <RequestHandler.get_login_url>`.
If you configure a login url with a query parameter, Tornado will
assume you know what you're doing and use it as-is. If not, it
will add a `next` parameter so the login page knows where to send
you once you're logged in.
"""
@functools.wraps(method)
def wrapper( # type: ignore
self: RequestHandler, *args, **kwargs
) -> Optional[Awaitable[None]]:
if not self.current_user:
if self.request.method in ("GET", "HEAD"):
url = self.get_login_url()
if "?" not in url:
if urllib.parse.urlsplit(url).scheme:
# if login url is absolute, make next absolute too
next_url = self.request.full_url()
else:
assert self.request.uri is not None
next_url = self.request.uri
url += "?" + urlencode(dict(next=next_url))
self.redirect(url)
return None
raise HTTPError(403)
return method(self, *args, **kwargs)
return wrapper
看起来似乎无法实现您想要的功能。当HTTP方法为GET且用户未登录时,Tornado将始终重定向到login_url而不仅仅返回403。您的理解是正确的吗?
英文:
Following is the implementation of method authenticated:
def authenticated(
method: Callable[..., Optional[Awaitable[None]]]
) -> Callable[..., Optional[Awaitable[None]]]:
"""Decorate methods with this to require that the user be logged in.
If the user is not logged in, they will be redirected to the configured
`login url <RequestHandler.get_login_url>`.
If you configure a login url with a query parameter, Tornado will
assume you know what you're doing and use it as-is. If not, it
will add a `next` parameter so the login page knows where to send
you once you're logged in.
"""
@functools.wraps(method)
def wrapper( # type: ignore
self: RequestHandler, *args, **kwargs
) -> Optional[Awaitable[None]]:
if not self.current_user:
if self.request.method in ("GET", "HEAD"):
url = self.get_login_url()
if "?" not in url:
if urllib.parse.urlsplit(url).scheme:
# if login url is absolute, make next absolute too
next_url = self.request.full_url()
else:
assert self.request.uri is not None
next_url = self.request.uri
url += "?" + urlencode(dict(next=next_url))
self.redirect(url)
return None
raise HTTPError(403)
return method(self, *args, **kwargs)
return wrapper
Seems there is no way to achieve what I want. When http method is GET, and if user didn't login, tornado will always redirect to login_url instead of just return 403.
Am I correct?
答案1
得分: 1
你可以在你的基础处理程序中覆盖获取用户的逻辑。
class BaseHandler(RequestHandler):
def get_current_user(self) -> Any:
"""Override to determine the current user from, e.g., a cookie.
This method may not be a coroutine.
"""
user = self.your_func_of_getting_user()
if user is None:
raise HTTPError(403)
return user
对于async
目的,你可以这样做:
class BaseHandler(RequestHandler):
_current_user: 'SomeUserModel | None' = None
...
async def prepare(self):
self._current_user = await self.your_async_func()
if self._current_user is None:
raise HTTPError(403)
英文:
You can override the logic of getting user in your Base Handler
class BaseHandler(RequestHandler):
def get_current_user(self) -> Any:
"""Override to determine the current user from, e.g., a cookie.
This method may not be a coroutine.
"""
user = self.your_func_of_getting_user()
if user is None:
raise HTTPError(403)
return user
for async
purposes you can do the next:
class BaseHandler(RequestHandler):
_current_user: 'SomeUserModel | None' = None
...
async def prepare(self):
self._current_user = await self.your_async_func()
if self._current_user is None:
raise HTTPError(403)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论