简体   繁体   English

是否可以使用 dj-rest-auth 缩短 email 确认密钥?

[英]Is it possible to make email confirmation key shorter with dj-rest-auth?

I am making a rest api for mobile application.我正在为移动应用程序制作 rest api。 I am using dj-rest-auth package for the overall authentication process.我正在使用dj-rest-auth package 进行整个身份验证过程。 Overall auth functionality works fine but One thing I want to modify is to make the email confirmation key shorter.整体身份验证功能工作正常,但我要修改的一件事是使 email 确认密钥更短。

User will get email like this.用户会像这样得到 email。

Please use this key to confirm your email.

MjE:1l7ZhR:f6U2RWlx2kEJY2jXzFuAuKpKclNyc3MpaKmeiEFGp3Y

In my email verify api user need to enter this whole key for verification.在我的 email 验证 api 用户需要输入整个密钥进行验证。

Is there any way to make this key shorter so that it will be good from user perspective(I think)?有没有办法让这个密钥更短,以便从用户的角度来看它会很好(我认为)?

I have made my custom adapter here.我在这里制作了我的自定义适配器。

class MyAdapter(DefaultAccountAdapter):
    def send_confirmation_mail(self, request, emailconfirmation, signup):
        current_site = get_current_site(request)
        activate_url = self.get_email_confirmation_url(
            request,
            emailconfirmation)
        ctx = {
            "user": emailconfirmation.email_address.user,
            "activate_url": activate_url,
            "current_site": current_site,
            "key": emailconfirmation.key,

        }

Looking at your code I guess you are using django-allauth ( https://github.com/pennersr/django-allauth ).查看您的代码,我猜您正在使用django-allauth ( https://github.com/pennersr/django-allauth )。

In this example I assumed that user is authenticated and verifcation code doesn't have to be unique.在此示例中,我假设用户已通过身份验证,并且验证码不必是唯一的。

If you want to create a shorter key and store it in db you should create custom model where key fits your needs ( 4 digit in this example - I assumed your user put in manually ):如果您想创建一个较短的密钥并将其存储在数据库中,您应该创建自定义 model key适合您的需求(本示例中为 4 位 - 我假设您的用户手动输入):

class ActivationKey(models.Model):
    user = models.ForeignKey(User, verbose_name=_("user"), on_delete=models.CASCADE)
    key = models.PositiveSmallIntegerField(_("key"))
    created_at = models.DateTimeField(auto_now_add=True)
    
    @classmethod
    def create(cls, user):
        key = random.randint(1000, 9999)
        return cls._default_manager.create(user=user, key=key)

We can generate key after user creation (override save() or use signal or create before sending email).我们可以在用户创建后生成密钥(覆盖 save() 或在发送电子邮件之前使用信号或创建)。 As you pointed you can override send_confirmation_mail so for simplicity in this example I use it:正如你所指出的,你可以覆盖send_confirmation_mail所以为了简单起见,在这个例子中我使用它:

class MyAdapter(DefaultAccountAdapter):
    def send_confirmation_mail(self, request, emailconfirmation, signup):
        current_site = get_current_site(request)
        ctx = {
            "user": emailconfirmation.email_address.user,
            "activate_url": reverse("account_confirm_key"),  # depends on you - if you need it at all
            "current_site": current_site,
            "key": ActivationKey.objects.create(user=user) # create key
        }
        if signup:
            email_template = "account/email/email_confirmation_signup"
        else:
            email_template = "account/email/email_confirmation"
        self.send_mail(email_template, emailconfirmation.email_address.email, ctx)

Next you should create custom endpoint for confirm code and activate user:接下来,您应该为确认代码创建自定义端点并激活用户:

 class VerifyUserView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):  # or change to get if more proper to you
        key = request.data.get("key")
        if not key:
            return Response({"error": _("Key is missing")}, status=status.HTTP_400_BAD_REQUEST)
        if not ActivationCode.objects.filter(user=request.user, key=key).exists():
           return Response({"error": _("Wrong activation key")}, status=status.HTTP_400_BAD_REQUEST)

        get_adapter(request).confirm_email(request, user.email)  # confirm method from adapter
        return Response({"status": "ok"})

And remember about settings: ACCOUNT_ADAPTER = MyAdapter并记住设置: ACCOUNT_ADAPTER = MyAdapter

About django-allauth:关于 django-allauth:

Default configuration ( https://dj-rest-auth.readthedocs.io/en/latest/configuration.html ) for email verification is ACCOUNT_EMAIL_CONFIRMATION_HMAC = True which means django would generate HMAC ( https://en.wikipedia.org/wiki/HMAC ) key. Default configuration ( https://dj-rest-auth.readthedocs.io/en/latest/configuration.html ) for email verification is ACCOUNT_EMAIL_CONFIRMATION_HMAC = True which means django would generate HMAC ( https://en.wikipedia.org/wiki /HMAC ) 密钥。 If you change option to False key will be generated and stored in EmailConfirmation model: https://github.com/pennersr/django-allauth/blob/da5ccdcf171e32ab1a438add3af38957f5a0659a/allauth/account/models.py#L100 but probably too long for you - 64 chars If you change option to False key will be generated and stored in EmailConfirmation model: https://github.com/pennersr/django-allauth/blob/da5ccdcf171e32ab1a438add3af38957f5a0659a/allauth/account/models.py#L100 but probably too long for you - 64 个字符

Another option is that you create short link (eg bit.ly) for user without changing anything.另一种选择是您为用户创建短链接(例如 bit.ly)而不更改任何内容。 Or maybe if this is for mobile application you can create deeplink, so after clicking confirmation link (even long) user will be redirect to mobile app and then mobile app send request to backend?或者,如果这是针对移动应用程序,您可以创建深度链接,因此在单击确认链接(甚至很长)后,用户将被重定向到移动应用程序,然后移动应用程序向后端发送请求?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM