首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用dj-rest-auth缩短电子邮件确认密钥?

是否可以使用dj-rest-auth缩短电子邮件确认密钥?
EN

Stack Overflow用户
提问于 2021-02-04 16:32:46
回答 1查看 139关注 0票数 1

我正在为移动应用程序制作一个rest api。我使用dj-rest-auth包进行整个身份验证过程。总体而言,身份验证功能运行良好,但我想修改的一件事是使电子邮件确认密钥更短。

用户将收到这样的电子邮件。

代码语言:javascript
复制
Please use this key to confirm your email.

MjE:1l7ZhR:f6U2RWlx2kEJY2jXzFuAuKpKclNyc3MpaKmeiEFGp3Y

在我的电子邮件验证api中,用户需要输入整个密钥进行验证。

有没有办法让这个密钥变得更短,这样从用户的角度看(我想)它是好的?

我在这里制作了我的自定义适配器。

代码语言:javascript
复制
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,

        }
EN

回答 1

Stack Overflow用户

发布于 2021-02-06 19:36:59

查看您的代码,我猜您使用的是django-allauth (https://github.com/pennersr/django-allauth)。

在本例中,我假设用户是经过身份验证的,并且验证代码不必是唯一的。

如果你想创建一个较短的密钥并将其存储在数据库中,你应该创建自定义模型,其中key适合你的需要(在这个例子中是4位数-我假设你的用户手动输入):

代码语言:javascript
复制
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)

我们可以在用户创建后生成密钥(覆盖save()或在发送电子邮件之前使用signal或create )。正如您所指出的,您可以覆盖send_confirmation_mail,因此为了简单起见,我在本例中使用它:

代码语言:javascript
复制
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)

接下来,您应该为确认代码和激活用户创建自定义端点:

代码语言:javascript
复制
 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"})

记住设置:ACCOUNT_ADAPTER = MyAdapter

关于django-allauth:

电子邮件验证的默认配置(https://dj-rest-auth.readthedocs.io/en/latest/configuration.html)是ACCOUNT_EMAIL_CONFIRMATION_HMAC = True,这意味着django将生成HMAC (https://en.wikipedia.org/wiki/HMAC)密钥。如果将选项更改为False,将生成密钥并将其存储在EmailConfirmation模型中:https://github.com/pennersr/django-allauth/blob/da5ccdcf171e32ab1a438add3af38957f5a0659a/allauth/account/models.py#L100,但对您来说可能太长了- 64个字符

另一种选择是为用户创建短链接(例如bit.ly),而不更改任何内容。或者,如果这是移动应用程序,你可以创建深度链接,这样点击确认链接(即使很长)后,用户会被重定向到移动应用程序,然后移动应用程序向后端发送请求?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66041939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档