【问题标题】:DRF Handling Password Reset EmailDRF 处理密码重置电子邮件
【发布时间】:2022-01-26 18:05:54
【问题描述】:

我是 Django Rest Framework 的新手,正在研究 DRF 和 React 身份验证系统。一切正常,除了密码重置。我遇到的问题是,当用户请求重置密码时,带有生成令牌的重置 URL 被触发到注册的电子邮件。因此,用户可以单击带有嵌入令牌的链接并返回调用(或任何其他)URL。
http://127.0.0.1:8000/api/auth/password_reset/validate_token/?token=wBBAIfQHzTJVz9bKPLkIgB 问题是如何生成视图或序列化程序以动态处理带有令牌的 URL。我只需要了解我正在使用“django-rest-passwordreset1.2.1”,(https://pypi.org/project/django-rest-passwordreset/) 包的完整流程,因此我使用模型生成重置电子邮件和令牌,根据文档触发信号以生成令牌并发送电子邮件。文档附带的端点在邮递员测试中验证并正常工作。我只是不确定如何在 Django 中创建该功能。任何帮助或链接到一个好的教程将不胜感激。 非常感谢提前

models.py

from django.dispatch import receiver
from django.urls import reverse
from django_rest_passwordreset.signals import reset_password_token_created
from django.core.mail import send_mail 

@receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, 
                                                                   **kwargs):
site = 'http://127.0.0.1:3000'

email_plaintext_message = "{}?token={}".format(reverse('password_reset:reset-password-validate'), reset_password_token.key)
reset_url = site + email_plaintext_message

send_mail(
    "Password Reset for {title}".format(title="Some website title"),
    reset_url,
    "noreply@somehost.local",
    [reset_password_token.user.email]
)

urls.py

urlpatterns = [
  path('api/auth', include('knox.urls')),
  path('api/auth/register', RegisterAPI.as_view()),
  path('api/auth/login', LoginAPI.as_view()),
  path('api/auth/user', UserAPI.as_view()),
  path('api/auth/logout', knox_views.LogoutView.as_view(), name="knox_logout"),
  path('api/auth/change-password/', ChangePasswordView.as_view(), name='change-password')
  path('api/auth/password_reset/', include('django_rest_passwordreset.urls')),
  path('admin/', admin.site.urls), 
]

include('django_rest_passwordreset.urls')) 提供以下网址: POST ${API_URL}/ - 使用 email 参数请求重置密码令牌* POST ${API_URL}/confirm/ - 使用有效令牌,将用户密码设置为提供的密码 POST ${API_URL}/validate_token/ - 如果给定的令牌有效,将返回 200 其中 ${API_URL}/ 是您的 urls.py 中指定的 url(例如,如上例中的 api/auth/password_reset/)*

【问题讨论】:

    标签: django-rest-framework change-password forgot-password reset-password


    【解决方案1】:

    好的,让我们从库中抽象出来,并获得适当的步骤来手动制作它。

    据我所知,您有一些令牌 token=wBBAIfQHzTJVz9bKPLkIgB 以某种方式与用户实例相关联,对吗?

    所以我们需要编写一个视图,允许我们进行身份验证并获取用户的请求,然后我们可以检查令牌并进行注销。

    from django.contrib.auth import logout
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.authentication import TokenAuthentication
    
    @api_view["GET"]
    @authentication_classes([TokenAuthentication])
    @permission_classes([IsAuthenticated])
    def logout(request):
       if request.query_params.get("token"):
           if Token.objects.filter(token=request.query_params["token"]).exists()
              logout(request)
    
              # other logic is here
    
              return Response({"status": "logged out"})
       return Response({"error": "..."})
    

    指向您的 urls.py 文件以在所需路径中使用此 API 视图。

    所以我在这里的假设是您使用类似TokenAuthentication 的东西,您可以将装饰器的参数更改为您的实际值。 permission_classes 装饰器也是如此。

    【讨论】:

    • 感谢您的提示好友,但也许我的问题表述不正确,我的问题不是身份验证令牌,而是为重置忘记的密码而生成的令牌。对于身份验证令牌,我使用 django-knox 和重置密码 django-rest-passwordreset 库。反正我已经解决了,下面回答。非常感谢您的提示
    【解决方案2】:

    问题出在前端,我能够通过替换 URL 来修改生成和存储令牌的模型中的参数。我变了

    email_plaintext_message = "{}?token={}".format(reverse('password_reset:reset-password-validate'), reset_password_token.key)
    

    到下面

        email_plaintext_message = "{}?token={}".format('http://127.0.0.1:3000/newpassword' , reset_password_token.key)
    

    现在返回网址是http://127.0.0.1:3000/newpassword?token=f109f93a83040895e3a8b1b8afd

    指向前端的正确组件。然后,我从 URL 中提取令牌并将其与新密码一起传递以进行验证,表单中的新密码击中所需的端点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 2012-03-09
      • 2017-08-21
      • 2018-02-23
      • 2015-11-26
      • 2017-01-25
      • 2020-02-15
      相关资源
      最近更新 更多