Я знаю, что это не первый вопрос такого рода, но другие темы мне не помогли. Я хочу использовать djangorestframework-simplejwt для аутентификации пользователя, и все в порядке, поскольку речь идет о получении пользователя. Я всегда получаю AnonymousUser.
Я получаю токен, посещая api / token и передавая учетные данные. Токен создан правильно, он содержит правильный идентификатор пользователя. Когда я пытаюсь получить доступ к защищенному представлению, это позволяет мне, но Django не распознает пользователя.
settings.py
import os
from datetime import timedelta
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ["SECRET_KEY"]
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"corsheaders",
"djmoney",
"bills",
"accounts",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "shared_bills.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
},
}
]
WSGI_APPLICATION = "shared_bills.wsgi.application"
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
# Authentication
AUTH_USER_MODEL = "accounts.User"
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = "/static/"
APPEND_SLASH = True
# CORS
CORS_ORIGIN_ALLOW_ALL = True
# Rest Framework
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
"DEFAULT_RENDERER_CLASSES": ["rest_framework.renderers.JSONRenderer"],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTTokenUserAuthentication"
],
}
if DEBUG:
REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"].append(
"rest_framework.renderers.BrowsableAPIRenderer"
)
REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"].extend(
[
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.BasicAuthentication",
]
)
# Simple JWT
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(weeks=1),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': os.environ["SECRET_KEY"],
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'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),
}
views.py"" "Приложение для просмотра учетных записей." ""
from django.contrib.auth import get_user
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin
from rest_framework.permissions import BasePermission, IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from accounts.models import User
from accounts.serializers import (
PasswordCheckSerializer,
UserChangePasswordSerializer,
UserSerializer,
)
class IsAnonymous(BasePermission):
"""Allows access only to anonymous users."""
def has_permission(self, request, view):
return not bool(request.user and request.user.is_authenticated)
class UserViewset(GenericViewSet, CreateModelMixin, RetrieveModelMixin):
"""Viewset for User object."""
queryset = User.objects.all()
def get_serializer_class(self):
if self.action == "register":
return UserSerializer
if self.action == "change_password":
return UserChangePasswordSerializer
if self.action == "delete_user":
return PasswordCheckSerializer
return UserSerializer
def get_object(self):
return get_user(self.request)
@action(detail=True, methods=["post"], permission_classes=[IsAnonymous])
def register(self, request, *args, **kwargs):
"""Registering new User."""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
@action(detail=True, methods=["post"], permission_classes=[IsAuthenticated])
def change_password(self, request, *args, **kwargs):
"""Changes password."""
user = self.get_object()
serializer = self.get_serializer(user, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({"detail": "password changed"}, status=status.HTTP_200_OK)
@action(detail=True, methods=["post"], permission_classes=[IsAuthenticated])
def delete_user(self, request, *args, **kwargs):
"""Deletes user."""
user = self.get_object()
serializer = self.get_serializer(user, data=request.data)
serializer.is_valid(raise_exception=True)
user.delete()
return Response({"detail": "user deleted"}, status=status.HTTP_200_OK)
Я считаю, что это что-то очевидное, потому что я начал изучать drf несколько дней go, но часы поиска в Google сделали не помогло.