Search code examples
node.jsreactjsexpressoauthwindow.open

Passing data from opened window


I've been stuck on this problem for a day now and was wondering if there's a way I could go about this.

client side

Client side is going to be dynamic since it's an app type plugin. The client side will open up a popup for oAuth purposes. Let's say its domain is www.google.com I have the popup written like window.open('www.backend.com/api') in ReactJS.

The client button is something like this:

<button onClick={() => iveBeenClicked()}> sync up </button>

and then it runs this function

const iveBeenClicked = (e) => {
e.preventDefault()
const popupWindow = window.open('www.backend.com/api', "_blank")

}

oAuth and backend with ExpressJS

This is the backend which we'll say is www.backend.com/api

router.use("/api", (req, res) => {

  if (req.query.code) {
   res.send(res.query.code)
  } else {
    res.redirect(
      `www.ApiRouteThatRedirectsWhenComplete.com`
    );
  }
});

Well I have the code I want, but how can I send that to the client from a different domain? If there's an alternative to window.open() where a user could press accept, please let me know.

So the big question is, how can client receive data from window.open's popup?

Thank you in advance!

#EDIT

So I finally got it thanks to @vishal-bartakke 's suggestion which I realized I implemented it wrong. I'm going to supply it here just in case it will help anyone that comes across this post.

for the ivebeenclicked() function in client side:

const iveBeenClicked = (e) => {
e.preventDefault()
const popupWindow = window.open('www.backend.com/api', "_blank")

//this is the part that was needed to receive the information of success
window.addEventListener('message', (e) => {
if (e.data) {
//do what you need to do with that key
}
})
}

in my expressjs's file:

router.use(['/api/', '/api/page?'], (req, res) => {

  if (req.query.token) {
    res.sendFile(path.join(__dirname +'/thatHTMLpage.html'))
  } else {
    res.redirect(`that route that does the oauth`)
  }
})

In that html created upon success, I added this code to send in the data

      window.onload = function () {
        let urlParams = new URLSearchParams(window.location.search);
        window.opener.postMessage(urlParams.get("code"), "*");
      };

It is quite a messy setup but it works how I want it. Thanks!


Solution

  • You can use postMessage (check here) to communicate between windows. In child window you can refer parent window as window.opener for posting message and in parent window you have popupWindow for posting