Djanog与React如何通过向用户发送电子邮件来重置用户密码 [英] Djanog with React how to reset user password by sending user an email
问题描述
我将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
.
- 用户提供
电子邮件
- 前端点击是具有
email
的API(即 - a)API确定用户是哪个
user
的email
,从而获得一个uid
b)为该用户
生成一个令牌
c)发送带有URL的电子邮件.该网址必须包含uid
和token
作为其一部分(例如,https://example.com/password-reset-confirm/<uid>/< token>
) - 用户单击此链接,它在前端显示一个页面,要求输入新的
密码
(注意此处:此url包含一个uid和一个令牌,稍后使用) - 用户提供了新的
密码
- 前端使用新给定的密码以及
uid
和token
(其中的API)进行API调用(即/api/password_reset_confirm/
)是网址的一部分) - API接收
uid
,令牌
和新的password
a)它检查uid
和token
是否有效(即token
与先前为同一user
的uid
)
b)设置该uid
的user
的新密码c)(可选)它可以使该用户退出系统
/api/password_reset/
)- User gives
email
- Frontend hit's an API (i.e.
/api/password_reset/
) with thatemail
- a) API determines which
user
'semail
it is and thus gets anuid
b) generates atoken
for thatuser
c) sends an email with an url. The url must contain theuid
andtoken
as part of it (for example,https://example.com/password-reset-confirm/<uid>/<token>
) - 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) - User gives a new
password
- Frontend makes API call (i.e.
/api/password_reset_confirm/
) with the newly given password, along with theuid
andtoken
(which were part of the url) - API receives
uid
,token
and newpassword
a) it checks if theuid
andtoken
are valid (i.e. thetoken
matches the one it previously generated for the sameuser
of thatuid
)
b) it sets the new password of theuser
of thatuid
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屋!