【问题标题】:DRF Simple JWT "No active account found with the given credentials"DRF Simple JWT“没有找到具有给定凭据的活动帐户”
【发布时间】:2021-11-15 10:10:48
【问题描述】:

我正在尝试使用 djangorestframework-simplejwt 获取访问权限并刷新 JWT 令牌。 我尝试使用 POST 方法访问 http://127.0.0.1:8000/api/token/ 端点,在 Postman 上发送用户名和密码作为请求数据,但响应为 "detail": "No active account found with the given credentials" 并带有 401 Unauthorized 错误代码。我也跑了python manage.py createsuperuser,但错误仍然出现。

下面是settings.py文件:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api.apps.ApiConfig',
    'rest_framework',
    'rest_framework.authtoken',
    'drf_spectacular',
    'rest_framework_simplejwt',
    'corsheaders',
]

from datetime import timedelta

...

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=1),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': False,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'username',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

serializers.py 中的用户序列化器

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = [
            'user_id',
            'username',
            'email',
            'password',
            'date_created',
        ]

models.py 中的用户模型:

class Users(models.Model):
    user_id = models.BigAutoField(primary_key=True)
    username = models.CharField(max_length=256)
    email = models.CharField(max_length=256)
    password = models.CharField(max_length=1024)
    date_created = models.DateField(auto_now_add=True)
    def __str__(self):
        return str(self.username)

views.py 中的用户注册视图:

class UserRegister(APIView):
    def post(self, request):
        user = request.data
        serializer = UserSerializer(data=user, context = {'request':request})
        if serializer.is_valid():
            user_saved = serializer.save(password=make_password(user['password']))
            return Response(user_saved,
                status=200)
        return Response({
            "error" : "Error encountered"},
            status=406)

还有 urls.py :

urlpatterns = [
    ...
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

【问题讨论】:

    标签: python django-rest-framework django-rest-framework-simplejwt


    【解决方案1】:

    问题出现是因为 default_user_authentication_rule(user)如果用户不是 none 并且用户具有 is_active true 状态,则返回 user。该类在rest_framework_simplejwt 库中的authentication.py 文件中可用。类的写法如下:

    def default_user_authentication_rule(user):
        # Prior to Django 1.10, inactive users could be authenticated with the
        # default `ModelBackend`.  As of Django 1.10, the `ModelBackend`
        # prevents inactive users from authenticating.  App designers can still
        # allow inactive users to authenticate by opting for the new
        # `AllowAllUsersModelBackend`.  However, we explicitly prevent inactive
        # users from authenticating to enforce a reasonable policy and provide
        # sensible backwards compatibility with older Django versions.
        return user is not None and user.is_active
    

    通过在用户模型中添加 is_active 列解决了该问题,如下所示:

    class Users(models.Model):
        user_id = models.BigAutoField(primary_key=True)
        username = models.CharField(max_length=256)
        email = models.CharField(max_length=256)
        password = models.CharField(max_length=1024)
        date_created = models.DateField(auto_now_add=True)
        is_active = models.BooleanField(default=True)
    
        def __str__(self):
            return str(self.username)
    

    并将 DRF Simple JWT 变量 'USER_ID_FIELD' 设置为 'username' 如下:

    SIMPLE_JWT = {
        ...
        'AUTH_HEADER_TYPES': ('Bearer',),
        'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
        'USER_ID_FIELD': 'username',
        'USER_ID_CLAIM': 'user_id',
        'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
    

    然后运行 ​​python manage.py makemigrations 后跟 python manage.py migrate 以应用用户模型更改。

    【讨论】:

      猜你喜欢
      • 2019-09-18
      • 2019-09-03
      • 1970-01-01
      • 2020-03-05
      • 2020-09-12
      • 2022-08-04
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多