Ошибка при активации по URL, отправленному на электронную почту, в системе регистрации пользователей с использованием DRF
Я хотел добавить систему регистрации к API, используя DRF. Пользователь получает url активации по электронной почте и может активировать свой аккаунт. У меня возникают проблемы с декодированием отправленного токена, т.е. токен воспринимается как недействительный.
views.py Я создал систему регистрации, а за ней последовала система активации.
class RegisterView(generics.GenericAPIView):
serializer_class = RegisterSerializer
def post(self, request):
user = request.data
serializer = self.serializer_class(data=user)
serializer.is_valid(raise_exception=True)
serializer.save()
user_data = serializer.data
user = User.objects.get(email=user_data['email'])
token = RefreshToken.for_user(user).access_token
current_site = get_current_site(request).domain
relativeLink = reverse('email-verify')
absolute_url = "http://" + current_site + relativeLink + "?token=" + str(token)
email_body = "Hi " + user.username + ". Use link below to verify your email \n" + absolute_url
data = {"email_body": email_body, "to_email": user.email, "email_subject": "Verify Your Email"}
Util.send_email(data)
return Response(user_data, status=status.HTTP_201_CREATED)
class VerifyEmail(views.APIView):
serializer_class = EmailVerificationSerializer
token_param_config = openapi.Parameter(
'token', in_=openapi.IN_QUERY, description='Description', type=openapi.TYPE_STRING)
@swagger_auto_schema(manual_parameters=[token_param_config])
def get(self, request, *args, **kwargs):
token = request.GET.get("token")
try:
payload = jwt.decode(token, settings.SECRET_KEY)
user = User.objects.get(id=payload['user_id'])
if not user.is_verified:
user.is_verified = True
user.save()
return Response({"email": "Successfully activated"}, status=status.HTTP_200_OK)
except jwt.ExpiredSignatureError:
return Response({'error': 'Activation expired'}, status=status.HTTP_400_BAD_REQUEST)
except jwt.exceptions.DecodeError:
return Response({"error": "Invalid token"}, status=status.HTTP_400_BAD_REQUEST)
serializers.py
from rest_framework import serializers
from .models import User
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(min_length=6, max_length=50, write_only=True)
class Meta:
model = User
fields = ['email', 'username', 'password']
def validate(self, attrs):
email = attrs.get('email', '')
username = attrs.get('username', '')
if not username.isalnum():
raise serializers.ValidationError("The username should only contain alphanumeric characters")
return attrs
def create(self, validated_data):
return User.objects.create_user(**validated_data)
class EmailVerificationSerializer(serializers.ModelSerializer):
token = serializers.CharField(max_length=555)
class Meta:
model = User
fields = ['token']
models.py Я воссоздал модели и добавил в них дополнительные поля.
class UserManager(BaseUserManager):
def create_user(self, username, email, password = None):
if username is None:
raise TypeError("Users should have a username")
if email is None:
raise TypeError("Users should hava a email")
email = self.normalize_email(email)
user = self.model(username = username, email = email)
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, password = None):
if password is None:
raise TypeError("Password should not be none")
user = self.create_user(username=username, email=email, password=password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=255, unique=True, db_index=True)
email = models.EmailField(unique=True, db_index=True)
is_verified = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def __str__(self):
return self.email
def tokens(self):
return ''