9

I am trying to implement the Google Oauth Feature. This is how my program runs. Firstly, the index.jsp file runs and opens a page like so: enter image description here

My index.jsp code is:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Website</title>
</head>
<style>
h1 {
 font-family: Bookman;
 font-size: 150px;
 font-style: normal;
 font-variant: normal;
 font-weight: 800;
 line-height: 26.4px;
 text-color: white;
 text-align: center;
}
p {
 font-family: Bookman;
 font-size: 50px;
 font-style: normal;
 font-variant: normal;
 font-weight: 800;
 line-height: 26.4px;
 text-color: white;
 text-align: center;
}
.main_background{
    background-image: url("img/main_page_background.jpg");
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}
</style>
<body class=main_background>
<h1 style="color:white">Title</h1>
<p style="color:white">Subtitle</p>
<form action="google_oauth" method="post">
<input type="submit" value="Sign In With Google"/>
</form>

</body>
</html>

What happens is the user clicks on a "Sign In With Google Button" that redirects to a servlet. Inside the servlet another html file is opened using the following code:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  File htmlFile = new File("C:\\Users\\neel-\\OneDrive\\Eclipse Workspace\\Website\\Website\\WebContent\\google_oauth.html");
  Desktop.getDesktop().browse(htmlFile.toURI());
 }

}

I understand that i could just implement this into the .jsp file but further on I will be needing the redirect. What happens after the html file opens we get a window like this.

enter image description here

The html file that is opened is the google_ouath.html file and the code is:

<!DOCTYPE html>
<html>
<head>
    <script src="jquery.js"></script>
    <script>
        var OAUTHURL    =   'https://accounts.google.com/o/oauth2/auth?';
        var VALIDURL    =   'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=';
        var SCOPE       =   'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
        var CLIENTID    =   '778647136201-d9trubpsuokohuj9a0c9bgufpo1qvqtf.apps.googleusercontent.com';
        var REDIRECT    =   'http://localhost:8080/Website/main_page'
        var LOGOUT      =   'http://accounts.google.com/Logout';
        var TYPE        =   'token';
        var _url        =   OAUTHURL + 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE;
        var acToken;
        var tokenType;
        var expiresIn;
        var user;
        var loggedIn    =   false;

        function login() {
            var win         =   window.open(_url, "windowname1", 'width=800, height=600'); 

            var pollTimer   =   window.setInterval(function() { 
                try {
                    console.log(win.document.URL);
                    if (win.document.URL.indexOf(REDIRECT) != -1) {
                        window.clearInterval(pollTimer);
                        var url =   win.document.URL;
                        acToken =   gup(url, 'access_token');
                        tokenType = gup(url, 'token_type');
                        expiresIn = gup(url, 'expires_in');
                        win.close();
                        validateToken(acToken);
                    }
                } catch(e) {
                }
            }, 500);
        }

        function validateToken(token) {
            $.ajax({
                url: VALIDURL + token,
                data: null,
                success: function(responseText){  
                    getUserInfo();
                    loggedIn = true;
                    $('#loginText').hide();
                    $('#logoutText').show();
                },  
                dataType: "jsonp"  
            });
        }

        function getUserInfo() {
            $.ajax({
                url: 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' + acToken,
                data: null,
                success: function(resp) {
                    user    =   resp;
                    console.log(user);
                    $('#uName').text('Welcome ' + user.name);
                    $('#imgHolder').attr('src', user.picture);
                },
                dataType: "jsonp"
            });
        }

        function gup(url, name) {
            name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
            var regexS = "[\\#&]"+name+"=([^&#]*)";
            var regex = new RegExp( regexS );
            var results = regex.exec( url );
            if( results == null )
                return "";
            else
                return results[1];
        }

        function startLogoutPolling() {
            $('#loginText').show();
            $('#logoutText').hide();
            loggedIn = false;
            $('#uName').text('Welcome ');
            $('#imgHolder').attr('src', 'none.jpg');
        }

    </script>
</head>

<body>
    <a href='#' onClick='login();' id="loginText"> Click here to login </a>
    <a href="#" style="display:none" id="logoutText" target='myIFrame' onclick="myIFrame.location='https://www.google.com/accounts/Logout'; startLogoutPolling();return false;"> Click here to logout</a>
    <iframe name='myIFrame' id="myIFrame" style='display:none'></iframe>
    <div id='uName'></div>
    <img src='' id='imgHolder'/>
</body>
</html>

However the relevant pieces of code for this problem is:

        function login() {
            var win         =   window.open(_url, "windowname1", 'width=800, height=600'); 

            var pollTimer   =   window.setInterval(function() { 
                try {
                    console.log(win.document.URL);
                    if (win.document.URL.indexOf(REDIRECT) != -1) {
                        window.clearInterval(pollTimer);
                        var url =   win.document.URL;
                        acToken =   gup(url, 'access_token');
                        tokenType = gup(url, 'token_type');
                        expiresIn = gup(url, 'expires_in');
                        win.close();
                        validateToken(acToken);
                    }
                } catch(e) {
                }
            }, 500);
        }

Here, the popup opens the client logs in and the popup closes. Like so. enter image description here

Above, we can see that the google login is done and the url has redirected. However going back to the login() function, the win.close() is not actually closing the popup. I was searching around on the web and I found a couple solutions that did not work. For example, here it states to use a workaround

open(location, '_self').close();

but that is not working either.

One more thing is that in Brock Adams Solution it states:

with one small exception, javascript must not be allowed to close a window that was not opened by that same javascript.

However, I do not think this is a problem.

Question: How to I get this popup to close when win.close() is not working.

UPDATE: After trying b4tch's anser. I get the following: enter image description here

XzibitGG
  • 330
  • 5
  • 18
  • If you add a console.log(e.message) in your catch statement, what does it say? – b4tch Jun 12 '18 at 10:07
  • @b4tch When adding the line of code in, the console is empty once the popup has redirected to the servlet. – XzibitGG Jun 21 '18 at 20:03
  • try an alert(e.message) instead, in case the console is clearing upon redirects – b4tch Jun 22 '18 at 08:00
  • I think you may have found the problem @b4tch . I edited question with what shows up. – XzibitGG Jun 22 '18 at 19:12
  • I tested in Chrome and received a similar message - "Blocked a frame with origin "null" from accessing a frame with origin "https://www.google.com". The frame requesting access has a protocol of "file", the frame being accessed has a protocol of "https". Protocols must match." - the same error occurs when served from an http-based file, so unless you can serve from an https-based file in your servlet (sorry, I have no idea about these) I don't think you can achieve what you need. – b4tch Jun 23 '18 at 09:58
  • I hate to bother you but I fixed the problem by redirecting to the HTML file instead of opening it using java. However, that isn't solving the problem of the popup not closing. – XzibitGG Jun 25 '18 at 02:18
  • I'm not sure I follow what you have done, if you can update your question I will gladly take a look – b4tch Jun 25 '18 at 08:42

1 Answers1

2

Javascript must not be allowed to close a window that was not opened by that same javascript. Which is done for security reasons.

It may just be that you must call self location object, which for configuring that opened window must be opened by same java script. For that if you try open(location, '_self').close(); instead of win.close() it should work which is the case with me. Ping me if it still does not work.

Haris Nadeem
  • 1,322
  • 11
  • 24
manan5439
  • 898
  • 9
  • 24
  • I replaced the "win.close()" in the login() function with open(location, '_self').close();. However, the popup does not close in the Eclipse Internal Browser nor Chrome nor Vivaldi. – XzibitGG Jun 21 '18 at 20:02