【问题标题】:allauth unverified email remains unverified once email expiresallauth 未验证的电子邮件在电子邮件过期后仍然未验证
【发布时间】:2020-05-29 18:53:36
【问题描述】:

我有一个自定义用户模型。我使用 Django rest auth 来处理用户的身份验证。 问题是在注册后发送电子邮件。如果用户在电子邮件过期之前没有验证它,它似乎会无限期地保持这样的状态。我希望在我的设置中自 ACCOUNT_EMAIL_VERIFICATION = "mandatory" 以来再次发送验证电子邮件,从文档中,它应该默认重新发送验证消息,但这并没有发生。我不知道还能做什么,似乎找不到任何有用的资源。

下面是我的模型

models.py

class User(AbstractBaseUser, PermissionsMixin):
    username = None
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=250)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(max_length=255, unique=True, blank=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

在我的 settings.py 中,用户的有效期为 2 天

ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS = True
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = None #or "api/authenticated/"
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1
ACCOUNT_EMAIL_CONFIRMATION_HMAC = False
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
EMAIL_VERIFICATION = "mandatory"
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "http"
ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN = 3600
ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 180
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = False
ACCOUNT_LOGOUT_ON_GET = True
ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = True
ACCOUNT_LOGIN_ON_PASSWORD_RESET = False
ACCOUNT_LOGOUT_REDIRECT_URL = "api/login/"
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE = False
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_USER_MODEL_EMAIL_FIELD = "email"

【问题讨论】:

    标签: django django-rest-framework django-allauth django-rest-auth


    【解决方案1】:

    最终,我能够以不同的方式解决这个问题,我创建了一个视图和 URL,请求用户发送电子邮件,然后在他们未验证时向他们发送链接。

    views.py

    from allauth.account.utils import send_email_confirmation
    from allauth.account.admin import EmailAddress
    from rest_framework.exceptions import APIException
    
    
    class EmailConfirmation(APIView):
        permission_classes = [AllowAny] 
    
        def post(self, request):
            user = get_object_or_404(User, email=request.data['email'])
            emailAddress = EmailAddress.objects.filter(user=user, verified=True).exists()
    
            if emailAddress:
                return Response({'message': 'This email is already verified'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                try:
                    send_email_confirmation(request, user=user)
                    return Response({'message': 'Email confirmation sent'}, status=status.HTTP_201_CREATED)
                except APIException:
                    return Response({'message': 'This email does not exist, please create a new account'}, status=status.HTTP_403_FORBIDDEN)
    

    urls.py

    path('verify-email/again/', qv.EmailConfirmation.as_view(), name='resend-email-confirmation'),
    

    【讨论】:

      【解决方案2】:

      首先,您提到您使用的是django-rest-auth,但事实并非如此,您可能使用的是django-allauth

      根据django-allauth的文档:

      ACCOUNT_EMAIL_VERIFICATION

      当设置为“强制”时,用户将被阻止登录,直到电子邮件地址得到验证。选择“可选”或“无”以允许使用未经验证的电子邮件地址登录。如果是“可选”,则仍然发送电子邮件验证邮件,而如果为“无”,则不发送电子邮件验证邮件。

      因此,如果第一封电子邮件过期,则没有提及重新发送验证电子邮件。要完成您想要的,您应该运行 job 脚本并检查 expired 验证令牌并手动重新发送验证电子邮件。

      您应该创建一个如下所示的脚本:

      from time import sleep
      from django.utils import timezone
      from django_allauth.account.models import EmailConfirmation
      
      while True:
          def_expired = timezone.now() - datetime.timedelta(days=app_settings.EMAIL_CONFIRMATION_EXPIRE_DAYS)
          expired_tokens = EmailConfirmation.objects.filter(sent__lte=def_expired)
          for token in expired_tokens:
              token.send()
          sleep(2)
      

      并使用您喜欢的任何调度程序(supervisorpm2cronjob 等)保持此脚本运行。

      底线,django-allauth 没有/不能拥有您想要的功能。这项工作需要手动完成。

      【讨论】:

        猜你喜欢
        • 2021-10-04
        • 2018-04-02
        • 1970-01-01
        • 2020-09-14
        • 2017-04-19
        • 1970-01-01
        • 2014-04-23
        • 1970-01-01
        相关资源
        最近更新 更多