diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
index 57d43ec..285b7fd 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
@@ -141,6 +141,26 @@ protected function getSiteMaintenanceMessage() {
   }
 
   /**
+   * Check if the user has cookies enabled.
+   *
+   * If the user was redirected to this page on an attempted login but the
+   * login didn't succeed, warn them about missing cookies.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The event to process.
+   *
+   * @see user_login_form_submit()
+   */
+  public function checkUserCookies(GetResponseEvent $event) {
+    /** @var \Symfony\Component\HttpFoundation\Request $request */
+    $request = $event->getRequest();
+    if (($request->query->get('state') === 'loggedin') && !$this->account->isAuthenticated()) {
+      $domain = ini_get('session.cookie_domain') ? ltrim(ini_get('session.cookie_domain'), '.') : $request->server->get('HTTP_HOST');
+      $this->drupalSetMessage($this->t('To log in to this site, your browser must accept cookies from the domain %domain.', ['%domain' => $domain]), 'error');
+    }
+  }
+
+  /**
    * Wraps the drupal_set_message function.
    */
   protected function drupalSetMessage($message = NULL, $type = 'status', $repeat = FALSE) {
@@ -152,6 +172,7 @@ protected function drupalSetMessage($message = NULL, $type = 'status', $repeat =
    */
   public static function getSubscribedEvents() {
     $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 30);
+    $events[KernelEvents::REQUEST][] = ['checkUserCookies'];
     $events[KernelEvents::EXCEPTION][] = array('onKernelRequestMaintenance');
     return $events;
   }
diff --git a/core/lib/Drupal/Core/Routing/RedirectDestination.php b/core/lib/Drupal/Core/Routing/RedirectDestination.php
index 873694a..1945e33 100644
--- a/core/lib/Drupal/Core/Routing/RedirectDestination.php
+++ b/core/lib/Drupal/Core/Routing/RedirectDestination.php
@@ -64,7 +64,7 @@ public function get() {
         $this->destination = $query->get('destination');
       }
       else {
-        $this->destination = $this->urlGenerator->generateFromRoute('<current>', [], ['query' => UrlHelper::buildQuery(UrlHelper::filterQueryParameters($query->all()))]);
+        $this->destination = $this->urlGenerator->generateFromRoute('<current>', [], ['query' => UrlHelper::filterQueryParameters($query->all())]);
       }
     }
 
diff --git a/core/modules/big_pipe/src/Tests/BigPipeTest.php b/core/modules/big_pipe/src/Tests/BigPipeTest.php
index a3f773e..51b8db1 100644
--- a/core/modules/big_pipe/src/Tests/BigPipeTest.php
+++ b/core/modules/big_pipe/src/Tests/BigPipeTest.php
@@ -6,6 +6,7 @@
 use Drupal\big_pipe\Render\BigPipe;
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Logger\RfcLogLevel;
 use Drupal\Core\Url;
 use Drupal\simpletest\WebTestBase;
@@ -86,7 +87,7 @@ public function testNoJsDetection() {
     $this->drupalLogin($this->rootUser);
     $this->assertSessionCookieExists(TRUE);
     $this->assertBigPipeNoJsCookieExists(FALSE);
-    $this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . base_path() . 'user/1" />' . "\n" . '</noscript>');
+    $this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . UrlHelper::encodePath(base_path() . 'user/1?state=loggedin') . '" />' . "\n" . '</noscript>');
     $this->assertNoRaw($no_js_to_js_markup);
     $this->assertBigPipeNoJsMetaRefreshRedirect();
     $this->assertBigPipeNoJsCookieExists(TRUE);
diff --git a/core/modules/system/src/Tests/Session/SessionHttpsTest.php b/core/modules/system/src/Tests/Session/SessionHttpsTest.php
index 8e25fd2..b8a09e2 100644
--- a/core/modules/system/src/Tests/Session/SessionHttpsTest.php
+++ b/core/modules/system/src/Tests/Session/SessionHttpsTest.php
@@ -132,7 +132,12 @@ protected function loginHttp(AccountInterface $account) {
 
     // Follow the location header.
     $path = $this->getPathFromLocationHeader(FALSE);
-    $this->drupalGet($this->httpUrl($path));
+    $parsed_path = parse_url($path);
+    $query = [];
+    if (isset($parsed_path['query'])) {
+      parse_str($parsed_path['query'], $query);
+    }
+    $this->drupalGet($this->httpUrl($parsed_path['path']), ['query' => $query]);
     $this->assertResponse(200);
   }
 
@@ -172,7 +177,12 @@ protected function loginHttps(AccountInterface $account) {
 
     // Follow the location header.
     $path = $this->getPathFromLocationHeader(TRUE);
-    $this->drupalGet($this->httpsUrl($path));
+    $parsed_path = parse_url($path);
+    $query = [];
+    if (isset($parsed_path['query'])) {
+      parse_str($parsed_path['query'], $query);
+    }
+    $this->drupalGet($this->httpsUrl($parsed_path['path']), ['query' => $query]);
     $this->assertResponse(200);
   }
 
diff --git a/core/modules/user/src/Form/UserLoginForm.php b/core/modules/user/src/Form/UserLoginForm.php
index 43b29e5..d9d33d6 100644
--- a/core/modules/user/src/Form/UserLoginForm.php
+++ b/core/modules/user/src/Form/UserLoginForm.php
@@ -129,11 +129,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $account = $this->userStorage->load($form_state->get('uid'));
 
-    // A destination was set, probably on an exception controller,
+    // A destination was set, probably on an exception controller.
     if (!$this->getRequest()->request->has('destination')) {
       $form_state->setRedirect(
         'entity.user.canonical',
-        array('user' => $account->id())
+        ['user' => $account->id()],
+        ['query' => ['state' => 'loggedin']]
       );
     }
     else {
diff --git a/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
index 34957c9..502ec07 100644
--- a/core/modules/user/src/Plugin/Block/UserLoginBlock.php
+++ b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\user\Plugin\Block;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\RedirectDestinationTrait;
@@ -94,7 +95,17 @@ public function build() {
     unset($form['pass']['#attributes']['aria-describedby']);
     $form['name']['#size'] = 15;
     $form['pass']['#size'] = 15;
-    $form['#action'] = $this->url('<current>', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]);
+
+    // Set the form action so that the user will be redirected to the current
+    // destination after logging in. Also append a query parameter to the
+    // destination in  so we can check later if the login was successful; see
+    // user_init().
+    $destination = $this->getDestinationArray();
+    $options = UrlHelper::parse($destination['destination']);
+    $options['query']['state'] = 'loggedin';
+    $destination['destination'] = $options['path'] . '?' . UrlHelper::buildQuery($options['query']);
+    $form['#action'] = $this->url('<current>', [], ['query' => $destination, 'external' => FALSE]);
+
     // Build action links.
     $items = array();
     if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
diff --git a/core/modules/user/src/Tests/UserBlocksTest.php b/core/modules/user/src/Tests/UserBlocksTest.php
index 9216a27..0eaa4e4 100644
--- a/core/modules/user/src/Tests/UserBlocksTest.php
+++ b/core/modules/user/src/Tests/UserBlocksTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\user\Tests;
 
+use Drupal\Core\Url;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -73,7 +74,8 @@ function testUserLoginBlock() {
     $this->assertNoText(t('User login'), 'Logged in.');
 
     // Check that we are still on the same page.
-    $this->assertUrl(\Drupal::url('user.admin_permissions', [], ['absolute' => TRUE]), [], 'Still on the same page after login for access denied page');
+    $url = Url::fromRoute('user.admin_permissions', [], ['absolute' => TRUE, 'query' => ['state' => 'loggedin']]);
+    $this->assertUrl($url, [], 'Still on the same page after login for access denied page');
 
     // Now, log out and repeat with a non-403 page.
     $this->drupalLogout();
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 90b813f..4801bc3 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -547,6 +547,19 @@ function user_login_finalize(UserInterface $account) {
 }
 
 /**
+ * Submit handler for the login form.
+ *
+ * Load current_user and perform standard login tasks. The user is then
+ * redirected to the My Account page. Setting the destination in the query
+ * string overrides the redirect.
+ */
+function user_login_form_submit($form, &$form_state) {
+  $account = User::load($form_state['uid']);
+  $form_state['redirect'] = ['user/' . $account->id(), ['query' => ['state' => 'loggedin']]];
+  user_login_finalize($account);
+}
+
+/**
  * Implements hook_user_login().
  */
 function user_user_login($account) {
diff --git a/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php b/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php
index fd99e99..2d733c3 100644
--- a/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\Core\Routing;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Routing\RedirectDestination;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
@@ -51,7 +52,7 @@ protected function setupUrlGenerator() {
       ->willReturnCallback(function($route, $parameters, $options) {
         $query_string = '';
         if (!empty($options['query'])) {
-          $query_string = '?' . $options['query'];
+          $query_string = '?' . UrlHelper::buildQuery($options['query']);
         }
 
         return '/current-path' . $query_string;
