[英]Cannot Authenticate Test Requests with Both User Token and API Key in Django Rest Framework
My project requires two authentication methods for some endpoints:我的项目需要对某些端点使用两种身份验证方法:
All works fine when working with the API using Postman or an iOS app, but I couldn't make the authentication work in my tests.使用 Postman 或 iOS 应用程序使用 API 时,一切正常,但我无法在我的测试中进行身份验证。 The user auth works fine, but the global key fails.用户身份验证工作正常,但全局密钥失败。
This is how the HTTP headers look in Postman:这是 HTTP 接头在 Postman 中的外观:
X-Api-Key: KEY_VALUE
Authorization: Token TOKEN_VALUE
I tried to experiment with the code in the shell and authentication worked fine using the exact same code used in the test.我尝试使用 shell 中的代码进行试验,并且使用测试中使用的完全相同的代码进行身份验证工作正常。 Only in the tests it fails so I'm not really sure how to debug this further.只有在测试中它才会失败,所以我不确定如何进一步调试。
You can see a complete project on github .你可以在 github 上看到一个完整的项目。
Test output:测试 output:
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test (app.tests.MyTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File ".../authtest/app/tests.py", line 21, in test
self.assertEqual(response.status_code, status.HTTP_200_OK)
AssertionError: 403 != 200
----------------------------------------------------------------------
Ran 1 test in 0.112s
FAILED (failures=1)
Destroying test database for alias 'default'...
When I open the shell with python manage.py shell
and copy and paste the test code:当我打开 shell 和python manage.py shell
并复制并粘贴测试代码:
>>> from rest_framework.test import (APITestCase, APIRequestFactory, force_authenticate)
>>> from rest_framework import status
>>> from accounts.models import User
>>> from app.views import MyView
>>> user = User.objects.create(email="test@test.com")
>>> user.set_password('1234')
>>> factory = APIRequestFactory()
>>> API_KEY = "KIkKSSz7.ziURxOZv8e66f28eMLYwPNs7eEhrNtYl"
>>> headers = {"HTTP_X_API_KEY": API_KEY}
>>> request = factory.get('/myview', **headers)
>>> force_authenticate(request, user=user)
>>> response = MyView.as_view()(request)
>>> response.status_code
200
Also making the request with postman works.也可以使用 postman 提出请求。 Any idea what's going on here?知道这里发生了什么吗?
The problem is the hardcoded API_KEY
you are passing in your test which is not a valid key resulting in status 403. I think the reason might be django uses a separate test database when running tests and djangorestframework-api-key uses APIKey model to generate api_key.问题是您在测试中传递的硬编码API_KEY
这不是导致状态 403 的有效密钥。我认为原因可能是 django 在运行测试时使用单独的测试数据库,而 djangorestframework-api-key 使用 APIKey model 生成 api_key .
You can confirm this by:您可以通过以下方式确认:
so what i might suggest is generating a new valid api_key and passing it instead of hardcoded key.所以我可能建议生成一个新的有效 api_key 并传递它而不是硬编码密钥。
Here i am sharing an updated test file of how you can carry out your test在这里,我将分享如何进行测试的更新测试文件
from rest_framework.test import (APITestCase, APIRequestFactory, force_authenticate)
from rest_framework import status
from accounts.models import User
from .views import MyView
from rest_framework_api_key.models import APIKey
class MyTests(APITestCase):
def test(self):
user = User.objects.create(email="test@test.com")
user.set_password('1234')
user.save()
factory = APIRequestFactory()
api_key, key = APIKey.objects.create_key(name="my-remote-service")
headers = {"HTTP_X_API_KEY": key}
request = factory.get('/myview', **headers)
force_authenticate(request, user=user)
response = MyView.as_view()(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.