Djanog与React如何通过向用户发送电子邮件来重置用户密码 [英] Djanog with React how to reset user password by sending user an email

查看:96
本文介绍了Djanog与React如何通过向用户发送电子邮件来重置用户密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将Django与React一起使用,我实现了一种当用户忘记密码时重置用户密码的方法.我的基本想法是:

I am using Django with React, I am implementing a method to reset user password when users forget their password. My basic idea is to:

1)用户提供其电子邮件地址

1) Users give their email address

2)向他们的电子邮件地址发送电子邮件,并带有链接以重置其密码(使用SendGrid api)

2) Send an email to their email adress with the link to reset their password(with SendGrid api)

3)用户输入新密码以重置密码

3) Users type in new password to reset their password

下面是我的序列化器,视图,URL和React代码

below is my serializers, views, urls and React code

//views.py
class PasswordResetConfirmSerializer(serializers.Serializer):
    new_password1 = serializers.CharField(max_length=128)
    new_password2 = serializers.CharField(max_length=128)
    uid = serializers.CharField()
    token = serializers.CharField()

    set_password_form_class = SetPasswordForm
    def custom_validation(self, attrs):
        pass
    def validate(self, attrs):
        self._errors = {}
        try:
            self.user = UserModel._default_manager.get(pk=attrs['uid'])
        except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
            raise ValidationError({'uid': ['Invalid value']})
        self.custom_validation(attrs)
        self.set_password_form = self.set_password_form_class(
            user=self.user, data=attrs
        )
        if not self.set_password_form.is_valid():
            raise serializers.ValidationError(self.set_password_form.errors)
        return attrs
    def save(self):
        return self.set_password_form.save()

// serializers.py
class PasswordResetConfirmView(GenericAPIView):
    serializer_class = PasswordResetConfirmSerializer
    permission_classes = (AllowAny,)

    @sensitive_post_parameters_m
    def dispatch(self, *args, **kwargs):
        return super(PasswordResetConfirmView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(
            {"detail": ("Password has been reset with the new password.")}
       )

//urls.py
path('api/passwordreset/confirm/',views.PasswordResetConfirmView.as_view(), name = 'password_reset_confirm')

// React 
    const config = {
    headers: {
      "Content-Type": "application/json"
      }
    };

    const body = JSON.stringify({ 
        new_password1: this.state.new_password,
        new_password2: this.state.confirm_password,
        uid: this.state.fetched_data.pk,
        token: this.state.fetched_data.token
    })

    axios.post(API_URL + 'users/api/passwordreset/confirm/', body, config)

我的重置密码功能本身可以正常工作.但是我在这里遇到的主要问题是,重置密码API需要"uid"和"token".为了获得这两个值,用户必须先登录(由于他们忘记了密码,这没有意义),或者调用api来获取"uid"和"token".我尝试了以下方法来获取这两个值:

My reset password function itself works fine. But the main problem I am having here is that the reset password API requires 'uid' and 'token'. In order to get these two values, users have to be either logged in, which makes no sense since they forget their password, or to call an api to get the 'uid' and the 'token'. I tried the below method to get those two values:

// views.py
class CustomObtainAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        response = super(CustomObtainAuthToken, self).post(request, *args, **kwargs)
        token = Token.objects.get(key=response.data['token'])
        return Response({'token': token.key, 'id': token.user_id})

// urls.py
path('api/authenticate/', CustomObtainAuthToken.as_view())

// React 
const body = { 
    password: 'mike',
    username: 'Abcd1234'
  }

  await axios.post(API_URL + 'users/api/authenticate/', body)

该函数的确返回正确的"uid"和"token",但是问题是我从用户那里得到的唯一东西就是电子邮件地址.我也无法获取密码和用户名来调用此API.所以我不太确定该怎么做.

The function does return the corret 'uid' and 'token', but the problem is that the only thing I am getting from the user is the email address. There is no way for me to also get the password and username to call this API. So I am not really sure how to do this.

有人可以告诉我正确的方法来完成这项工作吗?非常感谢.

Can someone show me the correct way to make this work? Thanks a lot.

推荐答案

首先,您可以从请求密码重置流程的用户电子邮件中获取 uid .其次,此令牌与您通过身份验证的用户的令牌不同.此令牌可以使用Django的 default_token_generator 生成>.

First of all, you can get the uid from the user's email who requested the password reset flow. And secondly this token is not the same token of your authenticated user. This token can be generated with django's default_token_generator.

  1. 用户提供电子邮件
  2. 前端点击是具有 email
  3. 的API(即/api/password_reset/)
  4. a)API确定用户是哪个 user email ,从而获得一个 uid
    b)为该用户
    生成一个令牌c)发送带有URL的电子邮件.该网址必须包含 uid token 作为其一部分(例如, https://example.com/password-reset-confirm/<uid>/< token> )
  5. 用户单击此链接,它在前端显示一个页面,要求输入新的密码(注意此处:此url包含一个uid和一个令牌,稍后使用)
  6. 用户提供了新的密码
  7. 前端使用新给定的密码以及 uid token (其中的API)进行API调用(即/api/password_reset_confirm/)是网址的一部分)
  8. API接收 uid 令牌和新的 password
    a)它检查 uid token 是否有效(即 token 与先前为同一 user uid )
    b)设置该 uid
    user 的新密码c)(可选)它可以使该用户退出系统
  1. User gives email
  2. Frontend hit's an API (i.e. /api/password_reset/) with that email
  3. a) API determines which user's email it is and thus gets an uid
    b) generates a token for that user
    c) sends an email with an url. The url must contain the uid and token as part of it (for example, https://example.com/password-reset-confirm/<uid>/<token>)
  4. This link is clicked by user, it shows a page in frontend, asking for a new password (notice here: this url contains an uid and a token that will be used later)
  5. User gives a new password
  6. Frontend makes API call (i.e. /api/password_reset_confirm/) with the newly given password, along with the uid and token (which were part of the url)
  7. API receives uid, token and new password
    a) it checks if the uid and token are valid (i.e. the token matches the one it previously generated for the same user of that uid)
    b) it sets the new password of the user of that uid
    c) optionally it may log that user out of the system

由于您正在使用DRF,因此请查看实现名为Djoser的身份验证库的实现.这可能是一个很好的学习经验.

Since you are using DRF, take a look at the implementation of an authentication library named Djoser. It can be a good learning experience.

这篇关于Djanog与React如何通过向用户发送电子邮件来重置用户密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆