12
votes

I am trying to incorporate google analytics graph at web app to show user statistics of their app usages. This is the local url http://192.168.100.10:9000/ i login to dashboard (web app) i have a google sign in button. So far here i maintain the session of the user after when he logs in.

And when user click on the sign in button. It triggers callback method. When callback is triggered first time then it has session maintained. I mean session("user") isn't null here.

public Result callback() {
    JsonNode jsonNode = Json.parse(session("user"));
    UserDTO userDTO = Json.fromJson(jsonNode, UserDTO.class);

    if (userDTO.getRole().getType().equals(RoleDTO.EnRoleType.ADMIN.toString()))
        return redirect(com.softoven.ultron.controllers.routes.AccountCTRL.index());
    if (request().queryString().get("code") != null && request().queryString().get("state") != null && request().queryString().get("state")[0].equals(session("state"))) { // Check if he/she is authorized
        session().remove("state");
        Analytics analytics = setAnalytics(userDTO, request());
        session("analytics", Json.toJson(analytics).toString());
        return redirect(com.softoven.ultron.controllers.routes.AccountCTRL.index());
    } else {  // Create Authorization URL
        String url = helper.buildLoginUrl();
        session("state", helper.getStateToken());
        return redirect(url);
    }
}

This is the url when user clicks on the sign in button https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=784122128025-cvq0fn1e23f24dia4soavsd9v1ovesub.apps.googleusercontent.com&redirect_uri=http://localhost:9000/callback&response_type=code&scope=https://www.googleapis.com/auth/analytics.readonly%20https://www.googleapis.com/auth/analytics.manage.users%20https://www.googleapis.com/auth/analytics%20https://www.googleapis.com/auth/analytics.edit%20https://www.googleapis.com/auth/analytics.manage.users.readonly%20https://www.googleapis.com/auth/analytics.provision&state=google-35808300 And when user click on the allow button on the permission page of the google sign in then control goes back to callback()

enter image description here

but this time session("user") is null. which shouldn't be null because i had set the session when user logged in. I don't know why is it happening and how to fix this.

And this is the end url after the redirect from google permission page. http://localhost:9000/callback?state=google-35808300&code=4/g-FkJ3GGS01jbeXLHK0o95ks-K-drGK7bxgzvi3cELU#

1
Are you using the Google Java Client library? If not it might greatly simplify what your are trying to do. - Matt
yes i am using google java client library. - Zeeshan Shabbir
IP/localhost? Align out to be the same or use a real domain name and retry (use hosts file to fake a real domainname). HTTP session is tied to a cookie and cookies are IP/domain specific. Browsers are also very strict on this, e.g. Chrome doesn't like a cookie domain being explicitly set to "localhost". - BalusC
I think that what @BalusC suggests was that you must use the same url consistently in your test. If you are testing with localhost, do not mix it with the ip version (192.168.100.10) since the browser will treat them as different hosts. The cookies from one host are not accessible by another one and Play uses cookies to store session information. - marcospereira
Zeeshan, if multiple people have commented on your post, use @nickname to notify the target person about a comment-reply, otherwise it goes unnoticed. Yes, you opened the page by an IP address and ended up in a localhost address. This is not correct. As said, cookies depend on IP/domain. Use the same IP or domain throughout the process and don't use "localhost". You can use hosts file to fake a real domain name. Let me know if that works then I will repost it in an answer. - BalusC

1 Answers

5
votes

This is the local url http://192.168.100.10:9000/ ...

... &redirect_uri=http://localhost:9000/ ...

And this is the end url after the redirect from google permission page http://localhost:9000/ ...

The starting URL is different from the ending URL. This is not correct.

Normally, the HTTP session in server side is tied to a session cookie. Cookies are in turn tied to a specific hostname (IP or domain). Webbrowsers are very strict in sending cookies to the specific hostname. Even though the IP would DNS-resolve to the correct domain, webbrowsers may refuse sending the cookie created on an IP address along with a request on the domain name. Basically, the webserver won't retrieve the originally created session cookie and hence creates a new one.

Then there exist webbrowsers who reject cookies whose hostname is explicitly set to "localhost", such as Google Chrome: Chrome doesn't create cookie for domain=localhost in broken https. Browsers may also choose to reject cookies whose hostname is explicitly set to an IP address because this may cause security trouble when client uses a dynamic IP.

It's therefore strongly recommended to use a real domain name such as example.com instead of an IP address or "localhost". Without buying one, you can fake one by simply editing the hosts file. The format of each line is like below, first the IP addres and thereafter the desired domains space separated.

127.0.0.1 localhost example.com anotherexample.com

Then consistently use exactly that domain throughout the process. Start at http://example.com:9000/..., use &redirect_uri=http://example.com:9000/... etc.

I don't do Play Framework, but if you're familiar with Servlet API, you may better understand the working of the HTTP session after reading this related Q&A: How do servlets work? Instantiation, sessions, shared variables and multithreading.