[英]password reset implementation with djoser
我想将djoser
用于重置密码功能,并按照文档:
PASSWORD_RESET_CONFIRM_URL
指向您的前端密码重置页面的 URL。 它应该包含 {uid} 和 {token} 占位符,例如
#/password-reset/{uid}/{token}
。 您应该传递 uid 和 token 来重置密码确认端点。
我做了以下工作:
PASSWORD_RESET_CONFIRM_URL': 'reset/password/reset/confirm/{uid}/{token}',
网址
url(r'^reset/password/reset/confirm/(?P<uid>[\\w-]+)/(?P<token>[\\w-]+)/$', PasswordResetView.as_view(),),
看法 :
class PasswordResetView(APIView):
def get (self, request, uid, token):
post_data = {'uid': uid, 'token': token}
return Response(post_data)
在我的邮件中,我得到了这个链接: http://127.0.0.1:8000/reset/password/reset/confirm/Mjk/538-954dccbc1b06171eff4d
: http://127.0.0.1:8000/reset/password/reset/confirm/Mjk/538-954dccbc1b06171eff4d
: http://127.0.0.1:8000/reset/password/reset/confirm/Mjk/538-954dccbc1b06171eff4d
很明显,我会得到:
{
"uid": "Mjk",
"token": "538-954dccbc1b06171eff4d"
}
作为我的输出,但我想在用户单击邮件中的链接时转到auth/password/reset/confirm
。
让我们首先描述动作:
然后,您可以使用以下方法重设密码。
#template
<p>Use the form below to change your password. Your password cannot be the same as your username.</p>
<form role="form" method="post">
{% csrf_token %}
<input type="password" name="password1" placeholder="New Password">
<input type="submit">
</form>
#view
from django.shortcuts import redirect, render
from djoser.conf import django_settings
def reset_user_password(request, uid, token):
if request.POST:
password = request.POST.get('password1')
payload = {'uid': uid, 'token': token, 'new_password': password}
url = '{0}://{1}{2}'.format(
django_settings.PROTOCOL, django_settings.DOMAIN, reverse('password_reset_confirm'))
response = requests.post(url, data=payload)
if response.status_code == 204:
# Give some feedback to the user. For instance:
# https://docs.djangoproject.com/en/2.2/ref/contrib/messages/
messages.success(request, 'Your password has been reset successfully!')
return redirect('home')
else:
return Response(response.json())
else:
return render(request, 'templates/reset_password.html')
捕获错误、处理重定向和添加默认渲染器类总是很重要的。 就我而言,我最终使用了以下内容。
#view
import requests
from django.contrib import messages
from django.contrib.sites.models import Site
from django.http import HttpResponseRedirect
from django.shortcuts import render
from rest_framework.decorators import (api_view, permission_classes,
renderer_classes)
from rest_framework.permissions import AllowAny
from rest_framework.renderers import JSONRenderer, TemplateHTMLRenderer
@api_view(('GET', 'POST'))
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
@permission_classes([AllowAny])
def reset_user_password(request, **kwargs):
# uses djoser to reset password
if request.POST:
current_site = Site.objects.get_current()
#names of the inputs in the password reset form
password = request.POST.get('new_password')
password_confirmation = request.POST.get('password_confirm')
#data to accept. the uid and token is obtained as keyword arguments in the url
payload = {
'uid': kwargs.get('uid'),
'token': kwargs.get('token'),
'new_password': password,
're_new_password': password_confirmation
}
djoser_password_reset_url = 'api/v1/auth/users/reset_password_confirm/'
protocol = 'https'
headers = {'content-Type': 'application/json'}
if bool(request) and not request.is_secure():
protocol = 'http'
url = '{0}://{1}/{2}'.format(protocol, current_site,
djoser_password_reset_url)
response = requests.post(url,
data=json.dumps(payload),
headers=headers)
if response.status_code == 204:
# Give some feedback to the user.
messages.success(request,
'Your password has been reset successfully!')
return HttpResponseRedirect('/')
else:
response_object = response.json()
response_object_keys = response_object.keys()
#catch any errors
for key in response_object_keys:
decoded_string = response_object.get(key)[0].replace("'", "\'")
messages.error(request, f'{decoded_string}')
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
# if the request method is a GET request, provide the template to show. in most cases, the password reset form.
else:
return render(request, 'account/password_reset_from_key.html')
我添加了 allowany 权限,因为 API 端点不需要任何身份验证。
在网址中;
path('password/reset/<str:uid>/<str:token>/',
reset_user_password,
name='reset_user_password'),
最后,在主设置文件中,我更新了 Djoser 重置密码 URL 以匹配我在上面构建的 URL,以便确保将用户重定向到我想要的页面。
DJOSER = {
"PASSWORD_RESET_CONFIRM_URL":
"dashboard/auth/password/reset/{uid}/{token}/",
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.