#python #django-rest-framework #django-rest-framework-simplejwt
Вопрос:
Я пытаюсь получить доступ и обновить токены JWT с помощью djangorestframework-simplejwt
. Я попытался попасть в http://127.0.0.1:8000/api/token/
конечную точку с помощью метода POST, отправив имя пользователя и пароль в качестве данных запроса на почтальона, но в ответ "detail": "No active account found with the given credentials"
получил 401 несанкционированный код ошибки. Я также выполнил запуск 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)
User registration view at 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'), ]
Ответ №1:
Проблема возникает из-за того, что класс default_user_authentication_rule(user)
возвращает пользователя, если пользователь не является никем, а у пользователя есть истинное состояние is_active. Класс доступен в authentication.py
файле внутри rest_framework_simplejwt
библиотеки. Класс записывается следующим образом :
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
примените изменения модели пользователей.