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(",");
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
});
}
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);
});
});
}
Top comments (0)