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

How to customize activate_url on django-allauth?

我正在使用 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 后端。

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

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

找不到任何指定此内容的文档(确保他们一定在某处),但查看 github 他们只是在 "account_confirm_email" [=15] 上做了 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,并且发现它非常简单。或许能满足您的需求。

我已经成功地通过覆盖 DefaultAccountAdapter class 和覆盖 django-allauth 文档中指定的 send_mail 方法从前端激活:

If this does not suit your needs, you can hook up your own custom mechanism by overriding the send_mail method of the account adapter (allauth.account.adapter.DefaultAccountAdapter)

我首先编写了用于确认电子邮件的后端 url :

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/<key>/

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

在 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 中)以“/”为根。这个returns一个像这样的URL,由javascript客户端处理:

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

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