How we built an account creation popup for Google and Outlook OAuth

Cover photo by Glenn Carstens-Peters on Unsplash

At Leave Me Alone we use Google and Microsoft OAuth for user sign in. To do this we redirect the user to the relevant login page, the user input their details, and is then directed back to our site and logged in. An unfortunate result of this is that our analytics report a great deal of referral traffic coming from “accounts.google.com” and “login.microsoft.com”.

To solve this problem, instead of redirecting it would be better if we could open a new window or popup for the OAuth flow. Also this is probably a better experience for the user than being redirected around.

How we implemented it

We use Passport for our authentication so when the user is directed back to our app after signing in the URL contains some parameters we need, including a token we use to authenticate them on our server.

Since we want to use a popup we need an additional step in the middle of the flow to catch that redirect, retrieve the URL parameters, close the popup, and use the token in the opening window (not the popup).

We allow users to sign in with Google and Outlook and the implementation is the same for both. For ease of reading the example will use Google.

Step 1: Open the popup

To open a new window we use Window.open() with the passport login URL (/auth/google in our case) which opens the “Sign in to Leave Me Alone with Google” page in a new window. We also give the window a name and pass the requested features we want it to have.

We assign the window reference and record the previous URL so that the same window will be used or focused if the user tries to click the sign in button again, even if it’s for a different provider. We don’t want two popups for different providers floating around causing confusion.

Finally, we add an event listener for messages as the popup is going to send the URL parameters and auth token when it’s finished.

To get the window to open as a popup instead of a new tab we had to request the features `menubar=no,toolbar=no`.

Step 2: Get the OAuth callback parameters in the popup

When the OAuth flow is complete Google redirects the user to a callback URL. Usually this would be a server route which would perform the Passport authentication. Since the auth is happening in a popup we use a page in our app, which when which when loaded grabs the search parameters and sends them to the parent.

This callback page uses a React Use Effect Hook which executes when the page loads. We fetch the URL parameters which will include the auth token and send them to the opening window (the parent) using Window.postMessage().

Step 3: Authenticate the user and redirect to the app

The OAuth flow is almost complete the and the popup is now closed, we just need to authenticate the user on our server.

The receive message function needs to check the origin of the message to make sure it’s from the same domain for security. While coding this we realised that several Chrome developer tools use postMessage() from the same origin so we also check the source before trying to extract the payload.

Once we have the OAuth parameters, we redirect to the user to our own authentication endpoint so that we can use Passport to authenticate and login.

Finished!

The process is quite simple and all we have done here is add an intermediary step in the OAuth flow to pass through the callback parameters.

There are probably lots of implementations but this was the quickest and simplest for us using React.js.

FAQs

How does the OAuth popup flow work for Google and Outlook in Leave Me Alone?

Leave Me Alone uses an OAuth popup for Google and Outlook sign-ins. When the user clicks "Sign in," a popup opens, allowing them to authenticate. Once the authentication is complete, the popup sends the authentication parameters to the parent window for further processing and authentication on the server.

Why did Leave Me Alone switch to an OAuth popup instead of redirecting users?

Redirecting users during the OAuth flow resulted in analytics showing misleading referral traffic from Google and Microsoft login pages. By using a popup, users experience a smoother login process, and analytics accurately reflect the traffic sources, improving data quality.

How does Leave Me Alone handle the OAuth callback parameters in the popup?

After the OAuth flow is completed in the popup, the callback page fetches the URL parameters, including the authentication token. These parameters are then sent to the parent window using window.postMessage(), allowing the parent window to complete the authentication process.

How does the security work when using the OAuth popup in Leave Me Alone?

Leave Me Alone uses a security check on the origin of the message received from the popup to ensure it's from the trusted domain. Additionally, when receiving data, the app verifies that the source is legitimate before using the OAuth parameters to authenticate the user.

What technologies did Leave Me Alone use to implement the OAuth popup?

Leave Me Alone used React.js to implement the OAuth popup. The solution involves opening a new window for the OAuth flow, receiving authentication details from the popup, and then securely handling the authentication process on the server.


Hopefully this helped you or provided some inspiration for your own solution.

Let us know if you have any questions or suggestions!