如何在 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/<key>/
我将activate_url
更改为我在settings.py
中指定的URL_FRONT
字符串,并附加了密钥以便从前端向我之前编写的url 发出get 请求(比如说http://localhost:8000/verify-email/<key>
)。 (之前将 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?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring WebFlux 上自定义未经授权的响应