Django-rest-framework API 测试 403 'detail': '您无权执行此操作。'

Posted

技术标签:

【中文标题】Django-rest-framework API 测试 403 \'detail\': \'您无权执行此操作。\'【英文标题】:Django-rest-framework API test 403 'detail': 'You do not have permission to perform this action.'Django-rest-framework API 测试 403 'detail': '您无权执行此操作。' 【发布时间】:2020-01-10 19:59:07 【问题描述】:

我目前正在编写一个测试来测试我的 get 请求,get 请求在我使用 django-rest-framework-simplejwt 来获取令牌以及将其用作默认身份验证类的标头中需要 jwt access_token

settings.py:

REST_FRAMEWORK = 
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAdminUser',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    # 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)

我的 test_api.py:

from rest_framework.test import APITestCase
from rest_framework import status
from rest_framework.test import APIClient 
from django.urls import reverse
from listing.models import Property
from backend.models import User

class PropertyTestCase(APITestCase):
    def setUp(self):
        property_1 = Property.objects.create(title="test", size=322.00, price=8000000, price_rent=300000, price_per_square_meter=500000, price_rent_per_square_meter=20000, description="description 1", type="sell", category="category 1", address="address 1", lat=21.027763, long=105.834160, images=["https://avatars2.githubusercontent.com/u/46511495?s=88&v=4"], contact_name="name 1", contact_address="test address 1", contact_phone="0923512213", contact_email="test@gmail.com", frontend=322, road=32, floor=4, bedroom=5, living_room=6, toilet=2, direction="Nam", balcony="Nam", meta_data="menu": "id": "file", "popup": "menuitem": ["value": "New", "onclick": "CreateNewDoc()", "value": "Open", "onclick": "OpenDoc()", "value": "Close", "onclick": "CloseDoc()"], "value": "File")
        property_1.save()
        property_2 = Property.objects.create(title="test2", size=322.00, price=8000000, price_rent=300000, price_per_square_meter=500000, price_rent_per_square_meter=20000, description="description 2", type="rent", category="category 2", address="address 2", lat=21.027763, long=105.834160, images=["https://avatars2.githubusercontent.com/u/46511495?s=88&v=4"], contact_name="name 2", contact_address="test address 2", contact_phone="0923512213", contact_email="test2@gmail.com", frontend=322, road=32, floor=4, bedroom=5, living_room=6, toilet=2, direction="Nam", balcony="Nam", meta_data="menu": "id": "file", "popup": "menuitem": ["value": "New", "onclick": "CreateNewDoc()", "value": "Open", "onclick": "OpenDoc()", "value": "Close", "onclick": "CloseDoc()"], "value": "File")
        property_2.save()
        self.property_1_id = property_1.id
        self.property_2_id = property_2.id
        self.client = APIClient()

        url = '/api/register'
        data = 
                "username": "dat12@icts.vn",
                "password": "123456",
                "confirm_password": "123456"
        

        response = self.client.post(url, data=data, format='json')
        self.access_token = response.json()['data']['access']


    def test_list_property_success(self):
        url = '/api/property/'
        data = 
                "page": 1,
                "page_size": 2,
        

        headers = 
            "Authorization": "Bearer ".format(self.access_token)
        
        self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + self.access_token)
        response = self.client.get(url, data=data, format='json', headers=headers)
        print(response.json())
        self.assertEqual(200, response.status_code)

我已经在邮递员中尝试了带有授权标头的 api,它有效,我还在测试中打印了访问令牌,它是正确的。

但是当我使用 403 代码和以下响应运行测试 test_list_property_success 当前响应时(在测试中打印)

'detail': '您没有执行此操作的权限。'

我已经设置了 self.client.credentials 并在 get 请求中添加了标头,我不知道还缺少什么。

任何帮助将不胜感激

【问题讨论】:

【参考方案1】:

找出原因,因为 DEFAULT_PERMISSION_CLASSES 设置为管理员用户,所以只有管理员角色的令牌可以在我的 api 中使用,所以我改为:

REST_FRAMEWORK = 
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    # 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)

现在成功了

【讨论】:

以上是关于Django-rest-framework API 测试 403 'detail': '您无权执行此操作。'的主要内容,如果未能解决你的问题,请参考以下文章

如何为 django-rest-framework api 编写单元测试?

django-rest-framework 和 swagger api 文档

如何使用 Django-oauth-toolkit 使用 Django-rest-framework 测试 API 端点以进行身份​​验证

在 HTML 页面或模板中使用 Django-REST-Framework 从在 Django 中创建的 API 获取/显示 API 数据

Django-rest-framework API 测试 403 'detail': '您无权执行此操作。'

无法使用视图名称 (django-rest-framework) 解析超链接关系的 URL