5

내 끝점에 대한 쿼리가 제대로 작동합니다 (유효한 토큰을 전달하는 한) 내 응답 데이터의 json 표현을 반환합니다.APIRequestFactory를 사용하여 토큰 기반 인증을 테스트하는 적절한 방법은 무엇입니까?

헤더에 인증 토큰을 전달, 내 엔드 포인트를 호출하는 서비스 API의 코드 : (

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

이 views.py에서, 내가보기에 디스패치 방법을 래핑하는 방법 장식이 viewsets을 .ReadOnlyModelViewSet) :

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'] 
: 나는 토큰을 사용하여 요청을 인증하는 테스트를 작성하기 위해 노력하고있어

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 

어떤 이유로이 테스트의 토큰을 제대로 전달할 수있는 요청을받을 수 없습니다. force_authenticate를 사용하면 토큰 유효성 검사에 사용중인 헤더가 변경되지 않는 것 같습니다. 현재 출력이 "PermissionDenied : Authentication failed."가 발생합니다. 요청에 토큰이 설정되어 있지 않기 때문입니다.

내 테스트의 요청 헤더에 이것을 설정하거나 내가 처음 사용하는 방식을 리펙토링하는 적절한 방법이 있습니까?

답변

11

시험을 통과 할 수있는 방법을 찾았지만이 문제를 처리하는 방법에 대해 더 잘 알고 있다면 게시하시기 바랍니다.

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

위의 두 줄의 테스트를 변경 한 후에는 토큰을 기반으로 올바르게 인증 된 것처럼 보입니다.

2
이 오래된 스레드를 위로 파고 죄송

하지만, 누군가가 자신의 테스트를 할 APIClient()를 사용하는 경우 다음을 수행 할 수 있습니다 :이 django-rest-framework-jwt tests이다와 내가 사용했습니다

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) 

정말 좋은 자원이 올

+0

'self.client = APIClient()'이 라인은 이미 가지고있는'APITestCase'로부터 상속 받기 때문에 필요하지 않습니다. –

관련 문제