我使用Django和Django REST framework作为后端,AngularJS作为前端。
对于用户管理,我使用django-rest-auth,它使用django-allauth进行用户管理。作为基础,我使用了django-rest-auth的demo。
问题是在您尝试验证通过激活网址发送电子邮件的电子邮件之后注册: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?
我设法通过覆盖DefaultAccountAdapter
类并覆盖django-allauth doc中指定的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()
电子邮件中发送的激活网址现在看起来像:http://127.0.0.1:9000/verify-email/<key>/
我将activate_url
更改为我在URL_FRONT
中指定的settings.py
字符串并附加了密钥,以便从前端发出请求到我之前写的url(让我们说http://localhost:8000/verify-email/<key>
)。 (之前将ACCOUNT_CONFIRM_EMAIL_ON_GET
设置为True
,以便通过执行get请求来确认电子邮件)
找不到任何指定这个的文档(确定它们必须在某处),但是看看github它们只是在"account_confirm_email"
上做了一个URL反转
你只需要在他们之后添加一个带有name="account_confirm_email"
param的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不使用它,它可能会破坏你。
如果您愿意使用其他库,我现在正在使用带有DRF的djoser,并且发现它非常简单。也许它符合您的需求。
基于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从请求的主机名中自动填充)。