User verification on reset password page

I am writing a reset password page for my site. Here is my idea:

and. The user clicks the link "forgot password" on the login page.

b. Redirect to my password - reset page

with. User enters their email address

e. An e-mail message sent to the e-mail address with a link to reset his / her password. The link has a security code, for example: code = "xxxx".

e. The user opens the link and enters a new password, and then click the submit button.

f. My page changes the user password.

My question is step f. In step e, when the user opened the link, I could check his security code, and then show the "new password" and "confirm password" fields to the user. But when the user clicked the submit button, how can I find out that this is a real request sent by the user, not the hacker? Maybe I'm wrong, but I think that a hacker can easily simulate such field data, since there are no validation fields.

There are some ideas that I can come up with to verify the request in step f, but I don't know if they are correct. 1. Add an encrypted cookie in step e and check it in step f? 2. Use the session variable in step e and check it in step f? 3. Add a hidden field in step e and check it in step f?

Are these approaches supported? Which one is better, or is there a better one?

.

+3
3

, reset, , . , . reset , , .

Edit:

, ASP.net.

, . PHP:

<?php
class AuthController extends Zend_Controller_Action
{
    public function identifyAction()
    {
        if ($this->_request->isPost()) {
            $username = $this->_getParam('username');
            $password = $this->_getParam('password');

            if (empty($username) || empty($password)) {
                $this->_flashError('Username or password cannot be blank.');
            } else {
                $user = new User();
                $result = $user->login($username, $password);

                if ($result->isValid()) {
                    $user->fromArray((array) $this->_auth->getIdentity());

                    if ($this->_getParam('changepass') || $user->is_password_expired) {
                        $this->_redirect('auth/change-password');
                        return;
                    }
                    $this->_doRedirect($user);
                    return;
                } else {
                    $this->_doFailure($result->getIdentity());
                }
            }
        }
        $this->_redirect('/');
    }

    public function forgotPasswordAction()
    {
        if ($this->_request->isPost()) {
            // Pseudo-random uppercase 6 digit hex value
            $resetCode = strtoupper(substr(sha1(uniqid(rand(),true)),0,6));

            Doctrine_Query::create()
                ->update('dUser u')
                ->set('u.reset_code', '?', array($resetCode))
                ->where('u.username = ?', array($this->_getParam('username')))
                ->execute();

            $mail = new Zend_Mail();
            $mail->setBodyText($this->_resetEmailBody($this->_getParam('username'), $resetCode));
            $mail->setFrom('no-reply@example.com', 'Example');
            $mail->addTo($this->_getParam('username'));
            $mail->setSubject('Forgotten Password Request');
            $mail->send();


            $this->_flashNotice("Password reset request received.");
            $this->_flashNotice("An email with further instructions, including your <em>Reset Code</em>, has been sent to {$this->_getParam('username')}.");
            $this->_redirect("auth/reset-password/username/{$this->_getParam('username')}");
        }
    }

    public function resetPasswordAction()
    {
        $this->view->username = $this->_getParam('username');
        $this->view->reset_code = $this->_getParam('reset_code');

        if ($this->_request->isPost()) {
            $formData = $this->_request->getParams();
            if (empty($formData['username']) || empty($formData['reset_code'])) {
                $this->_flashError('Username or reset code cannot be blank.');
                $this->_redirect('auth/reset-password');
            } elseif ($formData['new_password'] !== $formData['confirm_password']) {
                $this->_flashError('Password and confirmation do not match.');
                $this->_redirect('auth/reset-password');
            } else {
                $user = new User();
                $result = $user->loginWithResetCode($formData['username'], $formData['reset_code']);

                if ($result->isValid()) {
                    $user->updatePassword($result->getIdentity(), $formData['new_password']);

                    $user->fromArray((array) $this->_auth->getIdentity());
                    $this->_setLegacySessionData($user);

                    $this->_flashNotice('Password updated successfully!');
                    $this->_doRedirect($user);
                } else {
                    $this->_doFailure($result->getIdentity());
                    $this->_redirect('auth/reset-password');
                }
            }
        }
    }

    protected function _doFailure($username)
    {
        $user = Query::create()
            ->from('User u')
            ->select('u.is_locked')
            ->where('u.username = ?', array($username))
            ->fetchOne();

        if ($user->is_locked) {
            $lockedMessage = Config::get('auth.lock_message');
            if (!$lockedMessage) {
                $lockedMessage = 'This account has been locked.';
            }
            $this->_flashError($lockedMessage);
        } else {
            $this->_flashError('Invalid username or password');
        }
    }
}

, , . :

identifyAction

"" . .

forgotPasswordAction

, . reset, , , reset. , .

resetPasswordAction

"resetPassword". reset, . reset, reset . , changePassword, . ChangePasswordAction ( ) , () /, /resetCode

, .

+3

, , GUID , , - . - , , .

, c/d, .

0

StackOverflow forgot-password. .

0
source

Source: https://habr.com/ru/post/1727846/


All Articles