Automattic / wp-calypso

The JavaScript and API powered WordPress.com
https://developer.wordpress.com
GNU General Public License v2.0
12.4k stars 1.98k forks source link

Cookieless login wsod~ #52735

Open lsl opened 3 years ago

lsl commented 3 years ago

Blocking all cookies in Chrome and attempting to login to WordPress.com results in console errors when accessing localStorage.

This is sort of expected from a technical viewpoint but the UX can be improved by giving the user actionable feedback, explaining whats wrong and how to fix things.

Ultimately I'd like to see if we can leverage the work @jsnajdr has been doing on oauth (e.g. #52548) to enable an oauth login flow and calypso logged in experience that doesn't rely on cookies or localStorage.

Steps to reproduce the behavior

  1. Go to chrome://settings/cookies
  2. Select "Block all cookies"
  3. Go to https://wordpress.com
  4. Click "Login"

wsod

jsnajdr commented 3 years ago

When "Block all cookies" is enabled, Chrome blocks a lot of other non-cookie things, too. Accessing window.localStorage or window.sessionStorage throws an exception. Service workers are not registered. We'll need to guard all accesses to window.localStorage with a try/catch block detection:

let localStorageEnabled = false;
try {
  if ( window.localStorage ) {
    localStorageEnabled = true;
  }
} catch {}

Login with 3rd party cookies blocked The current /log-in dialog doesn't currently work on calypso.localhost even with the less strict "Block 3rd party cookies" options. That's because it sends an XHR POST request to wordpress.com/wp-login.php which is supposed to set wordpress.com session cookies in the response. But because the request is 3rd party, the response cookies are ignored and the login is a no-op.

The solution is to pass a get_bearer_token query parameter when config.isEnabled( 'oauth' ) and request an OAuth token in the response. Then we can store the token and proceed to a logged-in state.

To get the wordpress.com session cookies, too (for wp-admin etc.) we can do a first-party redirect loop after the OAuth login. By submitting a form:

<form method="POST" action="https://wordpress.com/wp-login.php">
  <input hidden name="log" value="username" />
  <input hidden name="authorization" value="Bearer mytoken" />
  <input hidden name="redirect_to" value={ window.location.href } />
</form>

the wp-login.php script sets session cookies in the response (as first party) and redirects back to Calypso. There's a <WpcomLoginForm> component in Calypso that does exactly this during signup flows.

Remote login links won't work The wp-login.php endpoint also returns a list of remote login links for mapped domains in token_links array. The remote login code in Calypso currently doesn't work and blocking 3rd party cookies only adds an additional reason:

CSP violation screenshot:

Screenshot 2021-05-11 at 10 31 10

With 3rd party cookies blocked, I'm afraid the remote login feature can't ever work again. We'd need to open new tabs or popups with the login links, or do redirect loops. That's very visible and disruptive for the user, unlike the iframes that were invisible.

To summarize, there's plenty of work to make the Calypso login compatible 🙂 I'll add a row to the Google spreadsheet.

josephscott commented 3 years ago

are Atomic sites supposed to have the /remote-login.php script

No, they should not be. And given the current state of things, as you described, these should probably go away entirely. They were developed back before Chrome announced complete removal of third-party cookie support and were designed to only deal with Safari ITP limitations at the time ( which have since become much tighter ).

With 3rd party cookies blocked, I'm afraid the remote login feature can't ever work again.

It certainly isn't going to ever work in the way it did before. Coming up with alternatives is something we are discussing.

lsl commented 3 years ago

With 3rd party cookies blocked, I'm afraid the remote login feature can't ever work again. We'd need to open new tabs or popups with the login links, or do redirect loops.

@josephscott are the Like RLT's working around this limitation with popups currently?

josephscott commented 3 years ago

The API tokens don't ever get you into a logged in state. They only make it possible to do authorized API calls.