Handling OAuth Redirecting
Tags: oauth, signin, javascript, authentication
Published: 2021-09-20 20:40:27

During this summer, I was working on an app that integrated Sketchfab (a platform for 3D Models) to allow users to import and visualize 3D models from their accounts. We wanted a seamless way to transition the user from logging in and authorizing back to our app, similar to how "Login with Google" works. This article is about how we implemented this transition.

Link to project: [3D Model World](https://3d-virtual-museum.netlify.app/)

![Google Sign in Screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ckqp4cyo9xbzlgmbtyno.png)
 

In order to import models from Sketchfab, the user has to have a Sketchfab account and authorize our app. In our app, the user clicks on the "Login to Sketchfab" button which takes the user to [sketchfab.com](https://sketchfab.com). Once in Sketchfab's website, the user will need to login or create an account. 

Afterwards, the user will be asked to authorize the app. Once the authorization process is completed, Sketchfab will redirect the user back to our app. This redirect is important because that's what makes OAuth secure.

![Example of Sketchfab's OAuth screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lej2e4w1hyqaprvaj2n8.png)

## Quick Implementation

One easy way to do this is to open the Sketchfab.com link in the same tab that the user is currently in.

``` javascript
function authenticate() {
    let AUTHENTICATION_URL = 'authentication_url_here';
    window.open(AUTHENTICATION_URL, "_self");
}
```
This works, but it means the user must exit the application and re-start it after login. We wanted a way to handle login while the app was still running.

## The Solution

What we want is after the user logs in, the token we get from Sketchfab (this is what we use to access the 3D models) is communicated back to the original tab. After we have communicated the token, we can now close the new window and update the original window with the new information.

We aimed to do something similar to how Google's login works: open a new tab or popup that will automatically redirect the user back to the original tab or window once the user is done with login. 

But how do we communicate across these tabs, the new tab and the original tab? 

We used local storage. Our implementation did the following:
* Open a new tab for the user to login to Sketchfab and authenticate our app. 
```javascript
function authenticate() {
    let AUTHENTICATION_URL = 'authentication_url_here';
    window.open(AUTHENTICATION_URL, "_blank");
}
```
* Set the redirect URI to a special page, such as my-web-app.com/finished-login. The purpose of this page will be to store the token in local storage and close itself when it is done. 
```javascript
function getTokenCloseWindow() {
    const user_token = # Get the user token after OAuth
    localStorage.setItem('user_token', user_token);
    window.close();
}
```
1. When getting the token or user information, it will be different for each website or authentication process.
2. The second window will then be closed with `window.close()`. 

* The original app will then listen for a "local storage" event, that's how we know we finished login and got the token. After getting the token, we then update the page to show that the user is now signed in and has access to the rest of the site. 

```javascript
$(window).on('storage', function (e) {
    var storageEvent = e.originalEvent;
    // code you want to run on change detected
})
```

To communicate between the two tabs, the Google OAuth JavaScript library uses [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage), which is a more secure way of communicating across tabs. Google does it this way because it prevents the possibilities of other applications from being able to read the token or information after authentication from local storage. 

##Thank you
Thank you for taking the time to read my article. Although there could be more ways of completing this process, I have talked about what I found to be a great approach. 

Let me know if you found this post helpful! If you have any comments, suggestions, or concerns feel free to reach out to me on [LinkedIn](https://www.linkedin.com/in/rjandrade/).