金字塔中的不同登录视图

时间:2015-06-30 07:13:04

标签: python pyramid

我的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

2 个答案:

答案 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')

然后在您需要返回403401的其他视图中,采用以下方式:

def another_view(request)
    ...
    raise YourError(HTTPForbidden)
    # or
    raise YourError(HTTPUnauthorized)
    ...

然后,您只需要在YourError类中实现处理逻辑。

答案 1 :(得分:1)

我遇到了一些看似可以解决这个问题的discussion on the Pyramid issues list

那就是说,我认为你可以做的是使用hooks覆盖Forbidden视图并创建一个自定义异常处理程序。然后在那里,我认为您可以区分403401错误,并重定向/显示相应的响应消息,并根据需要自定义响应。