我的Pyramid应用程序处理了一些URL。当未经身份验证的用户尝试打开任何URL时,用户将被重定向到登录表单:
def forbidden(request):
if request.user.keyname == 'guest':
return HTTPFound(location=request.route_url('auth.login',))
request.response.status = 403
return dict(subtitle=u"Access denied")
config.add_view(forbidden, context=HTTPForbidden, renderer='auth/forbidden.mako')
但对于某些网址(路由),我必须返回的不是登录表单,而是401 Unauthorized status code
的{{1}}标头。我如何设置我的路线来实现这一目标?我猜我必须使用WWW-Authenticate
。
答案 0 :(得分:4)
您可以将这两个错误包装到自定义错误中,并将其替换为两个错误。然后,您可以处理异常并为每个错误运行所需的方案。这是一个例子:
class YourError(HTTPException):
def __init__(self, error):
super(YourError, self).__init__()
self.error = error
def handle(self, request):
if error is HTTPForbidden or is instance(error, HTTPForbidden):
return self._handle403(request)
elif error is HTTPUnauthorized or is instance(error, HTTPUnauthorized):
return self._handle401(request)
def _handle403(self, request):
# do your stuff for 403
def _handle401(self, request):
# do your stuff for 401
# ...modify your view
def forbidden(context, request):
return context.handle(request)
然后编辑您的视图配置:
config.add_view(forbidden, context=YourError, renderer='auth/forbidden.mako')
然后在您需要返回403
或401
的其他视图中,采用以下方式:
def another_view(request)
...
raise YourError(HTTPForbidden)
# or
raise YourError(HTTPUnauthorized)
...
然后,您只需要在YourError
类中实现处理逻辑。
答案 1 :(得分:1)
我遇到了一些看似可以解决这个问题的discussion on the Pyramid issues list。
那就是说,我认为你可以做的是使用hooks覆盖Forbidden视图并创建一个自定义异常处理程序。然后在那里,我认为您可以区分403
和401
错误,并重定向/显示相应的响应消息,并根据需要自定义响应。