5

Truy vấn tới điểm cuối của tôi hoạt động tốt (miễn là tôi chuyển nó vào một mã thông báo hợp lệ), nó trả về biểu diễn json của dữ liệu phản hồi của tôi.Cách thích hợp để kiểm tra xác thực dựa trên mã thông báo bằng APIRequestFactory là gì?

Mã trong api dịch vụ mà các cuộc gọi đầu cuối của tôi, đi qua một thẻ auth trong tiêu đề:

headers = {'content-type': 'application/json', 
      'Authorization': 'Token {}'.format(myToken)} 
url = 'http://localhost:8000/my_endpoint/' 
r = session.get(url=url, params=params, headers=headers) 

Trong views.py, tôi có một trang trí phương pháp mà kết thúc tốt đẹp các phương pháp công văn trên view (viewsets .ReadOnlyModelViewSet):

def login_required(f): 
    def check_login_and_call(request, *args, **kwargs): 
     authentication = request.META.get('HTTP_AUTHORIZATION', b'') 
     if isinstance(authentication, str): 
      authentication = authentication.encode(HTTP_HEADER_ENCODING) 
     key = authentication.split() 
     if not key or len(key) != 2: 
      raise PermissionDenied('Authentication failed.') 
     user, token = authenticate_credentials(key[1]) 
     return f(request, *args, **kwargs) 
    return check_login_and_call 

tôi đang cố gắng để viết một bài kiểm tra để xác thực yêu cầu sử dụng một mã thông báo:

from rest_framework.authtoken.models import Token 
from rest_framework.test import APIRequestFactory 
from rest_framework.test import APITestCase 
from rest_framework.test import force_authenticate 

class EndpointViewTest(APITestCase): 
    def setUp(self): 
     self.factory = APIRequestFactory() 
     self.user = User.objects.create_user(
      username='[email protected]', email='[email protected]', password='top_secret') 
     self.token = Token.objects.create(user=self.user) 
     self.token.save() 

    def test_token_auth(self): 
     request = self.factory.get('/my_endpoint') 
     force_authenticate(request, token=self.token.key) 
     view = views.EndpointViewSet.as_view({'get': 'list'}) 
     response = view(request) 
     self.assertEqual(response.status_code, 200) 
     json_response = json.loads(response.render().content)['results'] 

Vì một lý do nào đó, tôi không thể nhận được yêu cầu chuyển đúng mã thông báo cho thử nghiệm này. Sử dụng force_authenticate dường như không thay đổi tiêu đề mà tôi đang sử dụng để xác thực mã thông báo. Đầu ra hiện tại đang tăng "PermissionDenied: Authentication failed." vì mã thông báo không được đặt theo yêu cầu.

Có cách nào thích hợp để thiết lập điều này trong tiêu đề yêu cầu trong thử nghiệm của tôi hoặc để cấu trúc lại cách tôi đang sử dụng nó ở nơi đầu tiên?

Trả lời

11

Tôi đã tìm được cách để vượt qua bài kiểm tra, nhưng vui lòng đăng nếu bạn có ý tưởng tốt hơn về cách xử lý bất kỳ điều nào trong số này.

request = self.factory.get('/my_endpoint', HTTP_AUTHORIZATION='Token {}'.format(self.token)) 
force_authenticate(request, user=self.user) 

Sau khi thay đổi hai dòng thử nghiệm trên, có vẻ như xác thực dựa trên mã thông báo chính xác.

2

Xin lỗi vì đào chủ đề cũ này lên, nhưng nếu ai đó đang sử dụng APIClient() để làm các xét nghiệm của họ, bạn có thể làm như sau:

from rest_framework.test import APITestCase 
from rest_framework.test import APIClient 
from rest_framework.authtoken.models import Token 
from django.contrib.auth.models import User 


class VehicleCreationTests(APITestCase): 

    def setUp(self): 
     self.client = APIClient() 
     self.user = User.objects.create_superuser('admin', '[email protected]', 'admin123') 
     self.token = Token.objects.create(user=self.user) 

    def testcase(self): 
     self.client.force_login(user=self.user) 
     response = self.client.post('/api/vehicles/', data=vehicle_data, format='json', HTTP_AUTHORIZATION=self.token) 
     self.assertEqual(response.status_code, 201) 

tài nguyên thực sự tốt mà tôi đã sử dụng để đưa ra đây là django-rest-framework-jwt tests

+0

'self.client = APIClient()' dòng này là không cần thiết vì bạn đang kế thừa từ 'APITestCase' đã có nó. –

Các vấn đề liên quan