使用 django rest 框架和 django oauth 工具包进行单元测试中的 oAuth 身份验证

Jad*_*Guo 5 django unit-testing oauth django-rest-framework

如何为需要 oAuth 身份验证的 API 端点编写单元测试?

简单地将 oAuth 令牌添加到请求标头是行不通的(可能是因为测试数据库不是持久的)。将装置加载到数据库中也无济于事。

我将 django-rest-framework 与 django-oauth-toolkit 一起使用。

我的 test.py 代码:

class Com_jm_Test(TestCase):
    fixtures=['oauth.json',]
    print 'test com jm'
    multi_db=True

    def test_list_job(self):
        self.client=Client(HTTP_AUTHORIZATION='Bearer 0cx2G9gKm4XZdK8BFxoWy7AE025tvq')
        response=self.client.get('/com-jm/jobs/')
        self.assertEqual(response.status_code,200)
Run Code Online (Sandbox Code Playgroud)

结果:

AssertionError: 401 != 200
Run Code Online (Sandbox Code Playgroud)

Dan*_*ral 8

这样做:

  1. 创建用户
  2. 创建应用程序
  3. 创建代币
...
    def __create_authorization_header(token):
        return "Bearer {0}".format(token)

    def __create_token(self, user):

        app = Application.objects.create(
            client_type=Application.CLIENT_CONFIDENTIAL,
            authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
            redirect_uris='https://www.none.com/oauth2/callback',
            name='dummy',
            user=user
        )
        access_token = AccessToken.objects.create(
            user=user,
            scope='read write',
            expires=timezone.now() + timedelta(seconds=300),
            token='secret-access-token-key',
            application=self.app
        )
        return access_token

    user = User(username='dummy', email='dummy@geneu.com')
    user.save()
    self.user = user
    token = __create_authorization_header(__create_token(user))
    response=self.client.get('/com-jm/jobs/', format='json', HTTP_AUTHORIZATION=token)
    self.assertEqual(response.status_code,200)
Run Code Online (Sandbox Code Playgroud)

当然,这必须适应您的需求,但这就是想法。对于未来的此类问题(当您在文档中没有找到足够的信息来归档您的目标时),我建议您查看源代码。例如,在这种情况下,您可以在工具包库的测试中找到如何执行此操作。( django-oauth-toolkit/oauth2_provider/tests/test_authorization_code.py )


Dee*_*bur 5

我面临同样的问题。这是我的解决方案。

DRF 提供APIClient发出请求。

APIClient类支持相同的请求接口Django的标准客户端类。这意味着标准.get(), .post(), .put(), .patch(), .delete(), .head().options()方法都可用。

还提供credentials方法可用于设置标头,然后将包含在测试客户端的所有后续请求中。

client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token AB7JSH^4454')
Run Code Online (Sandbox Code Playgroud)

DRF 文档

创建 Oauth 令牌

创建并获取用户

token = user.oauth2_provider_accesstoken.create(expires='expire_date', token='token')
Run Code Online (Sandbox Code Playgroud)

使用 APIClient 设置 Ouath 令牌

client = APIClient()
client.credentials(Authorization='Bearer {}'.format(token))
client.get(reverse('accounts_api:profile'))
Run Code Online (Sandbox Code Playgroud)

我们可以设置默认内容类型

REST_FRAMEWORK += {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}
Run Code Online (Sandbox Code Playgroud)

源代码的 Git 中心链接


Lau*_*Mat 2

查看 DRF 的测试文档,特别是“强制身份验证”一章。从这些文档中:

例如,当使用令牌强制进行身份验证时,您可能会执行如下操作:

user = User.objects.get(username='olivia')
request = factory.get('/accounts/django-superstars/')
force_authenticate(request, user=user, token=user.token)
Run Code Online (Sandbox Code Playgroud)