Search code examples
javascriptreactjsauthenticationreact-nativewindow

How do you access information about a child window in the parent window?


I'm currently trying to figure out how to use React to open a new child window, execute authenticate and then write back to the parent page that the authentication is complete.

I have a button labeled "Add New" which when you click on it opens a popup window that has a button on the page. When you click the button, a new window opens so that the customer can accept the OAuth request in their account, and then the window reroutes to the callback URL upon successful authentication. However, I want to be able to stop the customer from seeing it reroute, and rather have the window close upon successful auth completion, as well as for the parent page to have information written to it where I can see that the auth was done and trigger the next function. Any ideas on how to do this?

I tried going through the different Window functions to see if there was anything that returned the current URL of the child window, so that I could do an if statement that says when the URL = the callback URL, shut down the window and write to the page, but I've had no luck. It seems like once the new window opens, there's no information retained by the parent window about that window. Any ideas on how to get the information on the new child window written to the parent window would be greatly appreciated.

In case it would help, I pasted some of the functions below.

Below is the AuthButton component, which is called in the App component. The AuthButton component opens the popup, which includes the button that will open the authentication window.

<AuthButton
      activatePopup={this.activatePopup.bind(this)}
      auth={this.auth.bind(this)}
      showPopup={this.state.showPopup}
      closePopup={this.activateAuthPopup.bind(this)}
/>

This is the button component that opens up the new child window:

class Button extends Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    }
    render() {
        return (
            <div>
                <button 
                style={{
                    backgroundColor: "fff", 
                    backgroundImage: `url(${logo})`, 
                    backgroundSize: '70%', 
                    color: "#000", 
                    width: "18em", 
                    height: "10em", 
                    backgroundRepeat: "no-repeat", 
                    backgroundPosition: "center", 
                    margin: "10px",
                    borderStyle: "solid",
                    borderColor: "#000",
                    borderWidth: "2px",
                    borderRadius: "5px"
                }} 
                onClick = {
                    this.props.auth
                }></button>
          </div>
        );
    }
}

Within the App.js file in the App component there is an auth function (listed below). Axios is hitting a route in the app, and it returns the auth URL and we take that URL and execute window.open which opens a new window where the customer can authenticate.

  auth = () => {
      axios('/auth/oauth/authorize', {
        headers: {
          "Access-Control-Allow-Origin": true,
          'maxRedirects': 0
        }
      })
      .then(response => {
        console.log("Response", response);
        console.log("URL", response.data.href);
        var strWindowFeatures = "width=1000,height=800,resizable,scrollbars=yes,status=1";
        var windowpop = window.open(response.data.href, null, strWindowFeatures)
        console.log("Window Location Href", windowpop.location.href);
      })
      .catch(error => {
        console.log('Error fetching and parsing data', error);
      });
  }

The Window Location Href returns 'about:blank'.

Let me know if I can provide any other information! Thank you!


Solution

  • So to solve this issue, we are currently closing the window in the route functions when the auth is successful, and in the React function I am running a timer that looks for if window.closed is true or false, and if it is true than we are changing certain states.

    auth = () => {
          axios('/auth/oauth/authorize', {
            headers: {
              "Access-Control-Allow-Origin": true,
              'maxRedirects': 0
            }
          })
          .then(response => {
            var strWindowFeatures = "width=1000,height=800,resizable,scrollbars=yes,status=1";
            var windowpop = window.open(response.data.href, null, strWindowFeatures)
            this.setState({
              authUrl: response.data.href
            })
            windowpop.focus()
            var newThis = this; 
            var timer = setInterval(function() {   
                if(windowpop.closed) {  
                    clearInterval(timer);
                    newThis.setState({
                      logo: logo,
                      opacity: 0.5,
                      success: true
                    });
                    console.log('closed');  
                }  
            }, 1000); 
          })
          .catch(error => {
            console.log('Error fetching and parsing data', error);
          });
      }