[英]In Django's auth contrib module, how do I invoke the function that generates a password reset email?
[英]In Django's auth contrib module, how do I validate a token submitted from a reset password form?
我正在使用 Django 3.1 及其 auth contrib 模塊。 我有一個僅限 API 的應用程序,我在其中使用以下 Django 視圖啟動密碼重置
class ResetPasswordView(SuccessMessageMixin, PasswordResetView):
reset_password_template_name = 'templates/users/password_reset.html'
email_template_name = 'users/password_reset_email.html'
subject_template_name = 'users/password_reset_subject'
success_message = "We've emailed you instructions for setting your password, " \
"if an account exists with the email you entered. You should receive them shortly." \
" If you don't receive an email, " \
"please make sure you've entered the address you registered with, and check your spam folder."
success_url = reverse_lazy('users-home')
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
request.csrf_processing_done = True
return super().dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
email = json.loads(request.body).get('username')
try:
if User.objects.get(email=email).is_active:
form = PasswordResetForm({'email': email})
print("form valid? %s" % form.is_valid())
if form.is_valid():
request = HttpRequest()
request.META['SERVER_NAME'] = socket.gethostbyname('localhost') #'127.0.0.1'
request.META['SERVER_PORT'] = 8000
# calling save() sends the email
# check the form in the source code for the signature and defaults
form.save(request=request,
use_https=False,
from_email="laredotornado@yahoo.com",
email_template_name='../templates/users/password_reset_email.html')
print("email: %s " % email)
return super(ResetPasswordView, self).post(request, *args, **kwargs)
except Exception as e:
print("\n\nerror ...\n\n")
print(e)
# this for if the email is not in the db of the system
return super(ResetPasswordView, self).post(request, *args, **kwargs)
這會生成一個 email,其中會出現一個鏈接,看起來類似於
http://127.0.0.1:8000/password-reset-confirm/Mg/bhd3nc-29fa9003c9c61c2bda5cff0a66b38bdf/
我的問題是,如何將此令牌(帶有用戶所需的新密碼)提交回服務器,以便服務器驗證令牌然后更新用戶的密碼?
這取決於您的 API 實施的身份驗證策略。從您向用戶發送令牌這一事實來看,我假設您正在使用令牌身份驗證。 :) 這意味着在 API 端,您需要使用令牌身份驗證實現密碼重置端點。 不要忘記使令牌過期/列入黑名單。
另一種策略是使用 Django 密碼重置視圖運行密碼重置過程,而不會弄亂 API。
重用django.contrib.auth.views.PasswordResetConfirmView
,它調用self.token_generator.check_token(self.user, session_token)
。
import json
from django.contrib.auth.views import INTERNAL_RESET_SESSION_TOKEN, PasswordResetConfirmView
from django.views.decorators.csrf import csrf_exempt
class ConfirmResetPasswordView(PasswordResetConfirmView):
@csrf_exempt
def dispatch(self, request):
data = self.data = json.loads(request.body)
# self.user = self.get_user(data["uidb64"])
# self.token_generator.check_token(self.user, data['token'])
self.request.session[INTERNAL_RESET_SESSION_TOKEN] = data.pop('token')
data['token'] = self.reset_url_token
return super().dispatch(request, **data)
def get_form_kwargs(self):
return {
'data': self.data,
'user': self.user,
}
示例 POST 請求正文:
{
"uidb64": "Mg",
"token": "bhd3nc-29fa9003c9c61c2bda5cff0a66b38bdf",
"new_password1": "new_password",
"new_password2": "new_password"
}
生成一個唯一的令牌並將其與用戶 ID 一起發送到 URL 中的用戶地址 email。 用戶單擊 URL 並被重定向到可以輸入新密碼的頁面。 密碼和令牌被發送回服務器並進行驗證。 檢查令牌以確保它屬於正確的用戶並且沒有過期。 如果令牌有效,則為用戶更新密碼。
示例首先創建一個 URL 之類的
reset_password_link = f"http://localhost:8000/reset_password/{reset_password_token}?user_id={user.id}"
# send email with reset_password_link to user's email address
and then send this in mail and in reset_password page create a form which take new password and then validate it.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.