簡體   English   中英

在 Django 的 auth contrib 模塊中,如何驗證從重置密碼表單提交的令牌?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM