如何在 django-allauth 上自定义 activate_url?

Posted

技术标签:

【中文标题】如何在 django-allauth 上自定义 activate_url?【英文标题】:How to customize activate_url on django-allauth? 【发布时间】:2015-03-15 02:43:23 【问题描述】:

我使用 Django,Django REST framework 作为后端,AngularJS 在前端。

对于用户管理,我使用django-rest-auth,它使用 django-allauth 进行用户管理。作为基础,我使用了 django-rest-auth 的演示。

问题出在注册后,当您尝试验证它发送的带有激活 url 的电子邮件的电子邮件:127.0.0.1:8000/account/confirm-email/yhca8kmijle0ia7k3p7ztbvnd2n1xepn9kyeuaycmlzll5xw19ubjarnvjrot7eu/

其中 *127.0.0.1:8000 是 Django 后端。

但在我的情况下,它应该发送类似localhost:9000/#/verifyEmail/akv2dcvrfnk9ex5fho9jk0xx1ggtpfazmi8sfsoi2sbscoezywfp7kzcyqnizrc0 的网址。 这样验证将从前端完成,localhost:9000 是我的 AngularJS 前端。

有什么方法可以自定义 django-allauth 上的 activate_url 吗?

【问题讨论】:

你看到这个问题了吗? ***.com/questions/24128433/… 【参考方案1】:

在 Storm 的回答的基础上,我略有改进(也许在最初发布答案时这是不可能的)。 DefaultAccountAdapter 有一个特定的 get_email_confirmation_url 方法,可以覆盖该方法以生成电子邮件验证 URL,仅此而已。以下对我很有效。不需要在 urls.py 中输入。

在settings.py中

# Repoint this setting to a subclass of the DefaultAccountAdapter 
# so we can override how it handles account verification to allow 
# for usage in an SPA context.
ACCOUNT_ADAPTER = 'common.accountadapter.CustomAccountAdapter'
# An email verification URL that the client will pick up.
CUSTOM_ACCOUNT_CONFIRM_EMAIL_URL = "/verifyemail/?key=0"

在 common.accountadapter.py 中:

from allauth.account.adapter import DefaultAccountAdapter
from allauth.utils import build_absolute_uri
from django.conf import settings

class CustomAccountAdapter(DefaultAccountAdapter):

    def get_email_confirmation_url(self, request, emailconfirmation):
        url = settings.CUSTOM_ACCOUNT_CONFIRM_EMAIL_URL.format(emailconfirmation.key)
        ret = build_absolute_uri(
            request,
            url)
        return ret

在我的例子中,django 植根于“/backend”,而 javascript 客户端(在 Vue 中)植根于“/”。这会返回一个这样的 URL,由 javascript 客户端处理:

http://localhost/verifyemail/?key=MTc:1h4C9w:b0CIOekBNfirVSt-0-bHOSQQnjk

(localhost 会根据请求中的主机名自动填充)。

【讨论】:

【参考方案2】:

我已经设法通过覆盖DefaultAccountAdapter 类和覆盖 django-allauth 文档中指定的 send_mail 方法从前端进行激活:

如果这不符合您的需要,您可以通过覆盖帐户适配器的 send_mail 方法 (allauth.account.adapter.DefaultAccountAdapter) 来连接您自己的自定义机制

我首先写了我用来确认电子邮件的后端网址:

api_patterns = [
...
url(r'^verify-email/(?P<key>\w+)/$',
        confirm_email, name="account_confirm_email"),
...
]

然后我在settings.py 中指定了自定义适配器和前端 url,如下所示:

ACCOUNT_ADAPTER = 'API.adapter.DefaultAccountAdapterCustom'
URL_FRONT = 'http://localhost:9000/'

并在我的应用程序的adapter.py 中写了这个:

from allauth.account.adapter import DefaultAccountAdapter
from django.conf import settings

class DefaultAccountAdapterCustom(DefaultAccountAdapter):

    def send_mail(self, template_prefix, email, context):
        context['activate_url'] = settings.URL_FRONT + \
            'verify-email/' + context['key']
        msg = self.render_mail(template_prefix, email, context)
        msg.send()

电子邮件中发送的激活 URL 现在看起来像:http://127.0.0.1:9000/verify-email/&lt;key&gt;/

我将activate_url 更改为我在settings.py 中指定的URL_FRONT 字符串,并附加了密钥以便从前端向我之前编写的url 发出get 请求(比如说http://localhost:8000/verify-email/&lt;key&gt;)。 (之前将 ACCOUNT_CONFIRM_EMAIL_ON_GET 设置为 True 以便通过获取请求来确认电子邮件)

【讨论】:

这是我找到的最简单最好的解决方案。许多答案使用 allauth 视图来显示屏幕以验证电子邮件。但这应该由您的前端处理,因为其余 API 提供模板是无稽之谈。此解决方案可以发送包含前端 @ 的电子邮件,然后将访问其余 API。谢谢风暴! 使用 Vue:我让 /verify-email/:confirmationKey 传递到我的 Vue 路由器,从那里我渲染一个组件,该组件依次 ping rest-auth api 以确认密钥。效果很好 太棒了!但是你能解释一下如何使用类似的方法来重置密码吗?【参考方案3】:

找不到任何指定此内容的文档(确定它们一定在某处),但查看github 他们只是在"account_confirm_email" 上执行 URL 反向操作

您只需要在他们的后面添加一个带有name="account_confirm_email" 参数的urlpattern,如下所示:

from allauth.account.views import confirm_email

ulrpatterns= patterns('',
    ...
    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^verify-email/(?P<key>\w+)/$',
        confirm_email,
        name="account_confirm_email"),
)

问题在于,您现在正在直接解决依赖项的依赖关系。如果较新版本的 django-restauth 不使用它,它可能会对您造成影响。

如果您愿意使用其他库,我目前正在将 djoser 与 DRF 一起使用,并且发现它非常简单。也许它满足您的需求。

【讨论】:

以上是关于如何在 django-allauth 上自定义 activate_url?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django-allauth 进行自定义注册?

如何在 sylius 上自定义密码验证器?

如何在 Worklight 上自定义直接更新消息?

如何在 Spring WebFlux 上自定义未经授权的响应

如何在 macOS 10.12+ 上自定义 NSTableView 标头?

如何在 Spring Security Grails 上自定义 /login/authenticate?