DEV Community

Jose Álvarez
Jose Álvarez

Posted on • Updated on

JavaScript Social Auth with modal window

Hi, I'm going to explain how to implement social auth with modal window on Vue but can work on any other JavaScript Framework event in native JS.

The problem here is that when the modal window has been opened we loose the control to listen any event or request token when login or register is success.

We must think some way to receive an event when login is success and thus be able to recover the token, this event maybe launch from our back.

Let's go by parts.

Open modal

I'll asume that you know how to open a new window in JavaScript, so I'm not going to explain it in deep.

//This is my object with configurations for new window. 
window = null;
defaultOptions = {
    width: 500,
    height: 500,
    menubar: "no",
    resizable: "no",
    location: "yes",
    scrollbars: "no",
    centered: true,
  };

/
login(){
   const url = 'https://www.OurSocialAuthEndPoint.com'

   //When login is called open window is opened
   this. window = window.open(
    url, 
    null, 
    this.optionsToString(this.popupOptions)
   );
}

//Map the object with window options into string.
optionsToString = options =>
    Object.keys(options)
      .map(key => `${key}=${options[key]}`)
      .join(",");
Enter fullscreen mode Exit fullscreen mode

Well, the modal window open with our social login page, now we need to know if the user has registered.

Emit event.

In my case when user logged the back save it, and emit a JWT token that have to save in front-end as Cookie.

The problem is that JavaScript doesn't allow listen event on windows with other domain.

The solution I suggest is that pass token generated for the back-end by message event and our front-end will be listening that event.

My back emit a callback response, and emit postMessageEvent with token value.

In this way when callback page loads the message event will send and his value is the generated token.

Listen event

Once the event is send, we need to listen the event to capture the value that must be the token.

 token = null;
login(){
  //...open modal window code

onFetchToken();

saveToken()

this.window.close;
}


onFetchToken() {
   //Listen the message event to capture token.
  window.addEventListener("message", event => {
    const { data } = event;
    this.token = data.token
    });
  }
Enter fullscreen mode Exit fullscreen mode

The code above can look like correct but, is incorrect, because the event does't happens immediately, and we will save a null token and window will close but the user have't registered.

The solution is wait for the event occur asynchronously. For those we are going to use Promise, the promise is resolve only when the event occur and the window won't close.

//Remove token property

login(){
  //...open modal window code

  let token = await this.onFetchToken();

  saveToken(token)

  this.window.close;
}

onFetchToken() {
    return new Promise(resolve => {
      window.addEventListener("message", event => {
        const { data } = event;
        resolve(data.token);
      });
    });
  }
Enter fullscreen mode Exit fullscreen mode

Top comments (0)