Ste*_*han 4 django django-rest-framework reactjs
我正在使用 Django 和 React,我正在实现一种当用户忘记密码时重置用户密码的方法。我的基本想法是:
1) 用户提供他们的电子邮件地址
2) 向他们的电子邮件地址发送一封电子邮件,其中包含重置密码的链接(使用 SendGrid api)
3) 用户输入新密码以重置密码
下面是我的序列化器、视图、url 和 React 代码
//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)
Run Code Online (Sandbox Code Playgroud)
我的重置密码功能本身运行良好。但我遇到的主要问题是重置密码 API 需要“uid”和“token”。为了获取这两个值,用户必须登录(这没有任何意义,因为他们忘记了密码),或者调用 api 来获取“uid”和“令牌”。我尝试了以下方法来获取这两个值:
// 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)
Run Code Online (Sandbox Code Playgroud)
该函数确实返回了正确的“uid”和“令牌”,但问题是我从用户那里得到的唯一信息是电子邮件地址。我无法同时获得调用此 API 的密码和用户名。所以我不太确定该怎么做。
有人可以告诉我正确的方法来完成这项工作吗?多谢。
首先,您可以uid从请求密码重置流程的用户的电子邮件中获取。其次,这个令牌与经过身份验证的用户的令牌不同。该令牌可以使用 django 生成default_token_generator。
email/api/password_reset/)email user一个email,从而获取uidtoken为其生成 a useruid和token作为其一部分(例如,https://example.com/password-reset-confirm/<uid>/<token>)password(此处注意:此 url 包含一个 uid 和一个稍后将使用的令牌)password/api/password_reset_confirm/新给出的密码以及uid和token(是 url 的一部分)进行 API 调用(即 )uid,token和 new passworduid有效token(即与之前为该token密码生成的密码相匹配) b) 它设置该
密码的新密码
c) 可选地,它可以将该用户注销系统useruiduseruid由于您使用的是 DRF,因此请查看名为 Djoser 的身份验证库的实现。这可能是一次很好的学习经历。
| 归档时间: |
|
| 查看次数: |
4704 次 |
| 最近记录: |