5

對我的端點的查詢工作正常(只要我傳遞一個有效的標記),它就會返回我的響應數據的json表示。使用API​​RequestFactory測試基於令牌的身份驗證的正確方法是什麼?

調用我的終點,在頭傳遞一個身份驗證令牌在服務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):

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 

我試圖寫一個測試使用令牌驗證請求:

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'] 

出於某種原因,我無法獲得正確傳遞此測試令牌的請求。使用force_authenticate似乎不會更改我用於驗證令牌的標頭。當前輸出正在提高「PermissionDenied:身份驗證失敗。」因爲令牌沒有在請求中設置。

在我的測試中,是否有正確的方法在請求頭中設置此值,或者重構我首先使用它的方式?

回答

11

我找到了一種方法讓測試通過,但如果您對如何處理這些問題有更好的瞭解,請發佈。

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

在更改了上述兩行測試之後,似乎基於令牌進行了適當的驗證。

2

對不起,這挖舊線,但如果有人使用APIClient()做他們的測試,你可以做到以下幾點:來

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) 

,我用真正好的資源了,這是django-rest-framework-jwt tests

+0

'self.client = APIClient()'這行不是必需的,因爲你從已經擁有它的'APITestCase'繼承。 – 2017-11-08 16:13:48

相關問題