diff --git a/core/modules/user/src/Controller/UserController.php b/core/modules/user/src/Controller/UserController.php
index be15fac..495edaa 100644
--- a/core/modules/user/src/Controller/UserController.php
+++ b/core/modules/user/src/Controller/UserController.php
@@ -119,12 +119,11 @@ public function resetPass(Request $request, $uid, $timestamp, $hash) {
       // A different user is already logged in on the computer.
       else {
         /** @var \Drupal\user\UserInterface $reset_link_user */
-        if ($reset_link_user = $this->userStorage->load($uid)) {
+        if ($this->validPassResetHash($uid, $timestamp, $hash) && $reset_link_user = $this->userStorage->load($uid)) {
           drupal_set_message($this->t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please <a href=":logout">log out</a> and try using the link again.',
             ['%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout')]), 'warning');
         }
         else {
-          // Invalid one-time link specifies an unknown user.
           drupal_set_message($this->t('The one-time login link you clicked is invalid.'), 'error');
         }
         return $this->redirect('<front>');
@@ -170,10 +169,35 @@ public function getResetPassForm(Request $request, $uid) {
 
     /** @var \Drupal\user\UserInterface $user */
     $user = $this->userStorage->load($uid);
-    if ($user === NULL || !$user->isActive()) {
-      // Blocked or invalid user ID, so deny access. The parameters will be in
-      // the watchdog's URL for the administrator to check.
-      throw new AccessDeniedHttpException();
+
+    // Check whether the password reset URL is valid.
+    if (!$this->validPassResetHash($uid, $timestamp, $hash)) {
+      $current = REQUEST_TIME;
+      // Time out, in seconds, until login URL expires.
+      $timeout = $this->config('user.settings')->get('password_reset_timeout');
+      $current_user = \Drupal::currentUser();
+      if ($current_user->isAuthenticated() && $user != $current_user) {
+        // User is logged in - redirect to My Account.
+        drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid.'), 'error');
+        throw new AccessDeniedHttpException();
+      }
+      elseif ($user->getLastLoginTime() && $current - $timestamp > $timeout) {
+      // No time out for first time login.
+        drupal_set_message($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'error');
+        return $this->redirect('user.pass');
+      }
+      // Verify that the user exists and is active.
+      elseif (!$user->isActive()) {
+        // Blocked or invalid user ID, so deny access. The parameters will be in
+        // the watchdog's URL for the administrator to check.
+        drupal_set_message($this->t('The one-time login link you clicked is invalid.'), 'error');
+        return $this->redirect('user.pass');
+      }
+      else {
+        // Redirect to the password reset form.
+        drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'error');
+        return $this->redirect('user.pass');
+      }
     }
 
     // Time out, in seconds, until login URL expires.
@@ -203,44 +227,55 @@ public function getResetPassForm(Request $request, $uid) {
    */
   public function resetPassLogin($uid, $timestamp, $hash) {
     // The current user is not logged in, so check the parameters.
-    $current = REQUEST_TIME;
     /** @var \Drupal\user\UserInterface $user */
     $user = $this->userStorage->load($uid);
 
-    // Verify that the user exists and is active.
     if ($user === NULL || !$user->isActive()) {
-      // Blocked or invalid user ID, so deny access. The parameters will be in
-      // the watchdog's URL for the administrator to check.
-      throw new AccessDeniedHttpException();
-    }
-
-    // Time out, in seconds, until login URL expires.
-    $timeout = $this->config('user.settings')->get('password_reset_timeout');
-    // No time out for first time login.
-    if ($user->getLastLoginTime() && $current - $timestamp > $timeout) {
-      drupal_set_message($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'error');
       return $this->redirect('user.pass');
     }
-    elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && Crypt::hashEquals($hash, user_pass_rehash($user, $timestamp))) {
-      user_login_finalize($user);
-      $this->logger->notice('User %name used one-time login link at time %timestamp.', ['%name' => $user->getDisplayName(), '%timestamp' => $timestamp]);
-      drupal_set_message($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
-      // Let the user's password be changed without the current password
-      // check.
-      $token = Crypt::randomBytesBase64(55);
-      $_SESSION['pass_reset_' . $user->id()] = $token;
-      return $this->redirect(
-        'entity.user.edit_form',
-        ['user' => $user->id()],
-        [
-          'query' => ['pass-reset-token' => $token],
-          'absolute' => TRUE,
-        ]
-      );
-    }
+    
+    user_login_finalize($user);
+    $this->logger->notice('User %name used one-time login link at time %timestamp.', ['%name' => $user->getDisplayName(), '%timestamp' => $timestamp]);
+    drupal_set_message($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
+    // Let the user's password be changed without the current password
+    // check.
+    $token = Crypt::randomBytesBase64(55);
+    $_SESSION['pass_reset_' . $user->id()] = $token;
+    return $this->redirect(
+      'entity.user.edit_form',
+      ['user' => $user->id()],
+      [
+        'query' => ['pass-reset-token' => $token],
+        'absolute' => TRUE,
+      ]
+    );
+  }
 
-    drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'error');
-    return $this->redirect('user.pass');
+  /**
+   * Validate a password reset request.
+   *
+   * @param int $uid
+   *   User ID of the user requesting reset.
+   * @param int $timestamp
+   *   The current timestamp.
+   * @param string $hash
+   *   Login link hash.
+   *
+   * @return bool
+   *   Returns TRUE if the password reset request is valid.
+   *
+   * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+   *   If $uid is for a blocked user or invalid user ID.
+   */
+  protected function validPassResetHash($uid, $timestamp, $hash) {
+    /** @var \Drupal\user\UserInterface $user */
+    $user = $this->userStorage->load($uid);
+    $current = \Drupal::time()->getRequestTime();
+
+    if ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && Crypt::hashEquals($hash, user_pass_rehash($user, $timestamp)) && $user->isActive()) {
+      return TRUE;
+    }
+    return FALSE;
   }
 
   /**
diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/src/Tests/UserPasswordResetTest.php
index 528d38b..cdf6007 100644
--- a/core/modules/user/src/Tests/UserPasswordResetTest.php
+++ b/core/modules/user/src/Tests/UserPasswordResetTest.php
@@ -135,7 +135,7 @@ public function testUserPasswordReset() {
     // Log out, and try to log in again using the same one-time link.
     $this->drupalLogout();
     $this->drupalGet($resetURL);
-    $this->drupalPostForm(NULL, NULL, t('Log in'));
+    $this->assertUrl(Url::fromRoute('user.pass'));
     $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');
 
     // Request a new password again, this time using the email address.
@@ -160,15 +160,15 @@ public function testUserPasswordReset() {
     $bogus_timestamp = REQUEST_TIME - $timeout - 60;
     $_uid = $this->account->id();
     $this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account, $bogus_timestamp));
-    $this->drupalPostForm(NULL, NULL, t('Log in'));
-    $this->assertText(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'Expired password reset request rejected.');
+    $this->assertUrl(Url::fromRoute('user.pass'));
+    $this->assertText(t('You have tried to use a one-time login link that has expired.'), 'Expired password reset request rejected.');
 
     // Create a user, block the account, and verify that a login link is denied.
     $timestamp = REQUEST_TIME - 1;
     $blocked_account = $this->drupalCreateUser()->block();
     $blocked_account->save();
     $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp));
-    $this->assertResponse(403);
+    $this->assertText(t('The one-time login link you clicked is invalid.'), 'Blocked password reset request rejected.');
 
     // Verify a blocked user can not request a new password.
     $this->drupalGet('user/password');
@@ -187,7 +187,7 @@ public function testUserPasswordReset() {
     $this->account->setEmail("1" . $this->account->getEmail());
     $this->account->save();
     $this->drupalGet($old_email_reset_link);
-    $this->drupalPostForm(NULL, NULL, t('Log in'));
+    $this->assertUrl(Url::fromRoute('user.pass'));
     $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');
 
     // Verify a password reset link will automatically log a user when /login is
@@ -207,11 +207,11 @@ public function testUserPasswordReset() {
     $blocked_account = $this->drupalCreateUser()->block();
     $blocked_account->save();
     $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp) . '/login');
-    $this->assertResponse(403);
+    $this->assertText(t('The one-time login link you clicked is invalid.'), 'One-time link for blocked account is not valid.');
 
     $blocked_account->delete();
     $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp) . '/login');
-    $this->assertResponse(403);
+    $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link for deleted account is not valid.');
   }
 
   /**
