[英]Returning custom message when a permission is denied in DRF
Django REST Framework有一篇关于权限的优秀文档。 我已经能够使用预制的权限类,也可以构建我自己的权限类。
但是,在某些 API 方法中,“权限被拒绝”一般消息对用户来说信息量不大。 例如,如果用户已通过身份验证但帐户已过期,最好让用户知道他的帐户已过期,而不仅仅是权限被拒绝错误。
根据文档,在构建自定义权限类时,您可以返回True
或False
。 但是,如上所述,我想向用户显示更多信息。 如何做到这一点?
从 DRF 3.2.0 开始,您只需要添加一个 message 属性:
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
来自DRF
您可以简单地添加message
属性。
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
它将返回一个带有 key detail
的dict
,如下所示:
{
'detail': 'User is not superuser'
}
但是,例如,如果您希望
dict
键不是detail
而是errors
,那么return
错误 DRF 的方式将是相同的。
我们可以set message attribute
不是string
而是dict
,如下所示:
class IsSuperUserPermission(permissions.BasePermission):
message = {'errors': ['User is not a superuser']}
def has_permission(self, request, view):
self.message['errors'].clear()
return self.request.user.is_superuser
在这种情况下,错误将是:
{
'errors': ['User is not a superuser']
}
当未授予许可时,我将引发自定义响应的异常。 它适用于 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': 'need login'}
default_code = 'not_authenticated'
默认情况下,它由默认异常处理程序处理,并引发标准消息 - https://github.com/tomchristie/django-rest-framework/blob/2eb9107b875972e442ed73eef0e653fd4480d873/rest_framework/views.py#L82
但是,您可以在 DRF 的设置中设置自己的EXCEPTION_HANDLER
,并处理PermissionDenied
异常以返回您想要的消息。
请参阅http://www.django-rest-framework.org/api-guide/settings/ 上的说明
我在使用 DRF 3.9.4 时遇到了同样的问题。 作为一种解决方法,我在自定义权限类中只定义了一个简单的消息属性,并且它可以工作。 我猜你也可以使用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)
基于 Aysennoussi 的回答:
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
如果需要,您可以发送多个自定义消息。 您可以使用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 文件并以这种方式在permission_classes
列表中添加类Check_user_permission
:
class UserList(APIView):
permission_classes = (IsAuthenticated, Check_user_permission)
authentication_class = JSONWebTokenAuthentication
...
...
现在,如果您转到端点并发送 POST 请求,您将收到此响应。
{
"success": "false",
"message": "Post request is not allowed!",
"status_code": 403
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.