django 403 禁止 - 重定向到登录

Posted

技术标签:

【中文标题】django 403 禁止 - 重定向到登录【英文标题】:django 403 forbidden - redirect to login 【发布时间】:2014-05-02 01:59:21 【问题描述】:

遇到 403 Forbidden 时如何将用户重定向到登录页面?

考虑以下代码:

urls.py

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)

urlpatterns = patterns('',
    url(r'^', include(router.urls)),
)

views.py

class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer

        renderer_classes = (renderers.JSONRenderer, renderers.TemplatehtmlRenderer)
        template_name='rest_framework/users.html'

        def list(self, request, *args, **kwargs):
            response = super(viewSet, self).list(request, *args, **kwargs)
            if request.accepted_renderer.format == 'html':
                return Response('request':request, 'queryset': response.data['results'])
            return response

如果我在未登录的情况下访问 /domain/users,我会收到 403 Forbidden 错误。我想改为重定向到登录页面。换句话说,永远不要显示 403 错误,而是直接重定向到登录页面。

我试过把:

@login_required
def list(...):

但这不起作用。我假设是因为它在视图集中。

我也试过了:

def list(...):
    if not request.user.is_authenticated():
        return render_to_response('domain/login.html')

但还是不行。

我尝试了各种 403 中间件,但无济于事。

我尝试通过 urls.py 中的 handler403 处理程序进行重定向

handler403 = 'site.views.login'

没有成功。

怎么办?

Django 版本:1.5.4

【问题讨论】:

【参考方案1】:

您不能在类方法上使用标准的login_required 装饰器。当您在 URL 中使用 as_view() 时,您必须将其包装起来:

url(r'...', login_required(UserViewSet.as_view()))

或者用django.utils.decorators.method_decorator包装装饰器并将其应用到类dispatch方法:

from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required

class UserViewSet(viewsets.ModelViewSet):
...
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
    ....

(见https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-class-based-views)

对于基于类的视图,您可以将其合并到可重复使用的 PermissionRequiredMixin - 请参阅 https://***.com/a/6455140/839875

或者,您可以引发 django.core.exceptions.PermissionDenied 异常,Django 将使用 django.views.defaults.permission_denied 捕获该异常

(见https://docs.djangoproject.com/en/1.5/topics/http/views/#the-403-http-forbidden-view)

【讨论】:

这对我有用。非常感谢。 class UserViewSet(...) @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super(ProtectedView, self).dispatch(*args, **kwargs) 有一个简洁的 mixin,您也可以使用它,已将其添加到我的答案中

以上是关于django 403 禁止 - 重定向到登录的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 不会重定向到 403 上的 Keycloak 登录页面?

如何使授权属性返回自定义 403 错误页面而不是重定向到登录页面

Spring Boot 安全性 403 重定向

使用带有响应模式的重定向的httpErrors时出现403禁止错误

django:登录后重定向到引用页面[重复]

登录后 Django 重定向到仪表板