在DRF中拒绝权限时返回自定义消息

时间:2015-04-29 06:52:58

标签: django permissions django-rest-framework

Django REST Framework有关于权限的an excellent piece of documentation。我已经能够使用预先制作的权限类,并且还构建了自己的权限。

然而,有一些API方法,其中" Permission denied"通用消息对用户来说不是很有用。例如,如果用户已通过身份验证但帐户已过期,那么让用户知道他的帐户已过期而不仅仅是权限被拒绝错误会很好。

根据文档,在构建自定义权限类时,您可以返回TrueFalse。但是,如上所述,我希望向用户显示更多信息。如何做到这一点?

6 个答案:

答案 0 :(得分:14)

自DRF 3.2.0起,您只需添加消息属性:

from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission):
    message = 'Adding customers not allowed.'

    def has_permission(self, request, view): 

请参阅DRF文档:http://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

答案 1 :(得分:1)

来自DRF

您只需添加$sku->attach($attribute_id)属性。

$sku->attach($attribute_id, ['product_id' => $sku->product->id])

它将返回带有密钥message的{​​{1}},如下所示:

from rest_framework import permissions

class IsSuperUserPermission(permissions.BasePermission):
    message = 'User is not superuser'

    def has_permission(self, request, view):
        return self.request.user.is_superuser
  

但是,例如,如果您希望dict键不是detail而是{ 'detail': 'User is not superuser' } ,那么dict错误DRF的方式将是相同的。 / p>

我们可以detail不是errors,而是return,像这样:

set message attribute

在这种情况下,错误将是:

string

答案 2 :(得分:0)

我使用DRF 3.9.4遇到相同的问题。作为一种解决方法,我在自定义权限类中仅定义了一个简单的 message 属性,它可以正常工作。您也可以将 getattr 用于与我猜想相同的结果。

class IPWhitelistPermission(permissions.BasePermission):

    def __init__(self):
        super(IPWhitelistPermission, self).__init__()
        self._client_ip = None

    def has_permission(self, request, view):
        ip = get_client_ip(request)
        ret = IPWhitelist.is_whitelisted(ip)

        if not ret:
            logger = logging.getLogger('access')
            logger.warn("Unauthorized access from IP %s" % ip)
            self._client_ip = ip
        return ret

    @property
    def message(self):
        return "This IP is not whitelisted [{}]".format(self._client_ip)

答案 3 :(得分:0)

在不授予权限的情况下,我将引发一个自定义响应异常。 它适用于djangorestframewor(3.10.1)和django(2.2.3)。

from rest_framework.permissions import BasePermission
from rest_framework.exceptions import APIException
from rest_framework import status


class IsLogin(BasePermission):
    """
    Allows access only to authenticated users.
    """

    def has_permission(self, request, view):
        if request.email:
            return True
        raise NeedLogin()


class NeedLogin(APIException):
    status_code = status.HTTP_403_FORBIDDEN
    default_detail = {'error': True, 'message': '请先登录'}
    default_code = 'not_authenticated'

答案 4 :(得分:0)

建立在艾森诺西的答案之上:

from rest_framework import permissions
From django.utils import timezone

class CustomerAccessPermission(permissions.BasePermission):
    message = 'Adding customers not allowed.'

    def has_permission(self, request, view): 
        if request.user.has_expired:
            self.message = “Your account has expired.”
            return False
        elif request.user.has_access:
            return True
        else:
            return False

答案 5 :(得分:0)

如果需要,您可以发送多个定制消息。 您可以使用GenericAPIException来做到这一点。

步骤1:。创建一个Permissions.py文件并编写此代码。

class Check_user_permission(permissions.BasePermission):
def has_permission(self, request, view):
    if request.method in permissions.SAFE_METHODS:
        return True
    else:
        response ={
            "success": "false",
            'message': "Post request is not allowed for user from admin group",
            "status_code":403,
        }
        raise GenericAPIException(detail=response, status_code=403)

response 是您要发送的JSON响应。

步骤2:转到view.py文件,并通过以下方式在Check_user_permission列表中添加类permission_classes

class UserList(APIView):
    permission_classes = (IsAuthenticated, Check_user_permission)
    authentication_class = JSONWebTokenAuthentication
    ... 
    ...

现在,如果您转到端点并发送POST请求,您将收到此响应。

{
"success": "false",
"message": "Post request is not allowed!",
"status_code": 403
}