【问题标题】:Django responds to options request despite the lack of Authorisation token尽管缺少授权令牌,Django 仍响应选项请求
【发布时间】:2018-09-18 09:53:06
【问题描述】:

我正在测试来自 rest api 的响应。如果用户不发送令牌,我预计会发送 403 响应。

在测试(如下)中,我创建了一个用户,创建并获取他们的身份验证令牌(用于其他测试)并测试我是否可以在没有身份验证的情况下发送选项请求。

当使用外部请求测试端点时,我得到了响应:

{
    "detail": "Authentication credentials were not provided."
}

但我的代码在响应选项请求时返回状态 200。

我检查了代码中没有任何地方我 force_authentication(...self.client.credentials.__dict__) 返回一个空白字典。

为什么django在permission_classes = (permissions.IsAuthenticated,)时返回请求?

查看:

from rest_framework import permissions
class getUserOptions(views.APIView, ReturnMetadata):
    permission_classes = (permissions.IsAuthenticated,)
    def options(self, request):
        field_meta = self.user_metadata(request)
        return Response(field_meta)

测试:

from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.test import APIClient
from rest_framework.authtoken.models import Token

class basic_functionality(APITestCase, TestCase):

    def setUp(self):
        self.user_details = {...}
        self.client = APIClient()
        self.user_model = get_user_model()

        user = self.user_model.objects.create(username=self.user_details['username'])
        user.set_password(self.user_details['password'])

        user.first_name = self.user_details['first_name']
        user.last_name = self.user_details['last_name']
        user.email = self.user_details['email']
        ...
        user.is_active = self.user_details['is_active']
        user.save()

        self.client.force_login(user)

        user_temp = self.user_model.objects.get(username=self.user_details['username'])
        self.user_token = Token.objects.get_or_create(user=user_temp)[0]

class user_options(basic_functionality):

    def request_user_options(self, payload):
        """
        Test getting options for the user form
        called by test_user_options
        payload: 
            - Authorization : token
        """
        url = reverse('user_options')
        headers = {'Content-Type': 'multipart/form-data'}
        response = self.client.options(url, data=payload, headers=headers)

        return response

    def test_user_options_bad_token(self):
        payload = {}
        response = self.request_user_options(payload)
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

【问题讨论】:

    标签: django authentication django-rest-framework


    【解决方案1】:

    似乎force_login 在您的APIClient 中为您提供了一个会话,这意味着您不必验证后续请求。这不是我个人想要实现的目标,因为这不是具有我的身份验证设置的用户所需要的体验。

    我必须设置self.client.force_authenticate(user=None)

    来自docs

    登录: login 方法的功能与 Django 的常规 Client 完全相同 班级。这允许您针对任何包含 SessionAuthentication 的视图对请求进行身份验证。

    # Make all requests in the context of a logged in session.
    client = APIClient()
    client.login(username='lauren', password='secret')
    

    未验证:

    要取消验证后续请求,请调用 force_authenticate 将用户和/或令牌设置为无。

    client.force_authenticate(user=None)
    

    【讨论】:

      猜你喜欢
      • 2016-03-08
      • 1970-01-01
      • 2022-09-23
      • 2017-10-03
      • 1970-01-01
      • 2019-07-06
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多