Django Rest Framework JWT 身份验证测试

Posted

技术标签:

【中文标题】Django Rest Framework JWT 身份验证测试【英文标题】:Django Rest Framework JWT Authentication Test 【发布时间】:2015-06-01 08:39:43 【问题描述】:

我正在设置 DRF 以使用 JWT 令牌身份验证。我似乎处于 DRF-JWT 说它工作正常,但我无法成功运行登录测试的地步。

我已经完成了django-rest-framework-jwt docs 中的安装步骤,并且能够成功运行 curl $ curl -X POST -d "username=admin&password=abc123" http://localhost:8000/api-token-auth/ 并取回令牌。

我希望我的测试也能将令牌传回给我,但显然我没有正确设置它。

# tests.py
class LoginTests(APITestCase):
    def setUp(self):
        self.user = NormalUserFactory.create()
        self.jwt_url = reverse('jwt_login')

    def test_token_get_not_allowed(self):
        # do not allow GET requests to the login page
        response = self.client.get(self.jwt_url)
        self.assertEqual(response.data.get('detail'), 'Method "GET" not allowed.')

    def test_token_login_fail_incorrect_credentials(self):
        # pass in incorrect credentials
        data = 
            'username': self.user.username,
            'password': 'inCorrect01'
        
        response = self.client.post(self.jwt_url, data)
        self.assertEqual(response.data.get('non_field_errors'), 
            ['Unable to login with provided credentials.'])

    def test_token_login_success(self):
        data = 
            'username': self.user.username,
            'password': 'normalpassword',
        
        response = self.client.post(self.jwt_url, data)
        print(response.data.get("token"))
        self.assertNotEqual(response.data.get("token"), None)

前两个单元测试成功运行,但第三个不会返回令牌,而是返回 'non_field_error':'Unable to login with provided credentials.',这是我在凭据不正确时所期望的。

要创建用户实例(和其他模型实例),我使用的是 factory_boy。这种创建实例的相同方法适用于该项目中的其他应用程序以及其他项目,并且我已验证该用户确实存在于测试数据库中。

# factories.py
class UserFactory(DjangoModelFactory):
    class Meta:
        model = User

    native_language = 'es'


class NormalUserFactory(UserFactory):
    username = 'normaluser'
    password = 'normalpassword'
    email = 'user@email.com'
    first_name = 'John'
    last_name = 'Doe'

这也是我的相关设置:

# settings.py
REST_FRAMEWORK = 
    'API_ROOT': '/v1/',
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),


JWT_AUTH = 
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=14)

【问题讨论】:

您应该使用User.set_password 来设置密码。 password 字段包含哈希。 【参考方案1】:

试试下面的代码:

tests.py

class LoginTests(APITestCase):
    def setUp(self):
        self.user = NormalUserFactory.create()
        self.jwt_url = reverse('jwt_login')    
    def test_post_form_failing_jwt_auth(self):
            """
            Ensure POSTing form over JWT auth without correct credentials fails
            """
            data = 
                'username': self.user.username,
                'password': 'inCorrect01'
            
            response = self.client.post(self.jwt_url, data)
            self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

【讨论】:

以上是关于Django Rest Framework JWT 身份验证测试的主要内容,如果未能解决你的问题,请参考以下文章

DRF:如何将 django-rest-framework-jwt 集成到 Djoser

Django Rest Framework 中的 JWT 身份验证错误“无效签名”

Django Rest Framework JWT 身份验证测试

Django-Rest-Framework JWT 单元测试说“未提供身份验证”

Django Rest Framework 避免身份验证 JWT

如何让 django-rest-framework-jwt 在注册时返回令牌?