dkellycollins
dkellycollins

Reputation: 497

How to determine if user has logged out on another page

I am running a Google App Engine project where everytime the user takes an action I want to check to see if the user is 1)logged in 2)an admin. This is the code I have for the appuser:

class AppUser 
{
    private UserService userService;
    private User user;

    public AppUser()
    {
        userService = UserServiceFactory.getUserService();
        user = userService.getCurrentUser();
    }

    public IsAdministrator()
    {
        if(IsLoggedIn())
        {
            return userService.IsUserAdmin();
        }
        return false;
    }

    public IsLoggedIn()
    {
        return user == null;
    }
}

When I log out with my app this works fine. However, if I log out on another page (like on google calendars or something) the app still thinks I'm logged in. Is there another better way to check if the user is still logged in?

Also I know that this can be done with security-constraint in the web.xml however that will not work in this case as I need to take certain actions if the user has logged off.

I am using App Engine SDK 1.7 and GWT SDK 2.4

Upvotes: 0

Views: 959

Answers (2)

James Synge
James Synge

Reputation: 632

I ran into this today, though it was worse: I'd logged out as user A (from a Google Sites page), and logged in as user B, but my GAE app still thought I was logged in as user A. Argh.

The reason for this is that there are two cookies involved, one for tracking which Google user is logged into Google, and another for tracking which GAE application user is logged into my GAE application. Recall that a GAE could be using any federated authentication service, not just Google's. My application has no access to the google.com cookies, so I can't directly check whether user A is still logged in (or which user is currently logged in).

Unfortunately, I've not yet found a straight forward "federated logOUT" mechanism, though it is possible that Google Identity Toolkit can be used for detecting that the expected user is no longer logged in.

I found others discussing this issue:

Update

I came up with a solution that works for my application, where I have a page that redirects the user, a student, to his or her classroom's home page. Since this is accessed infrequently by any one student (a few times a day), but which needs to know which student is logged in, I took the following approach which works for me:

  1. User goes to page A, which clears the ACSID and SACSID cookies, and redirects to Google for the user to login.
  2. User is probably already logged in, so Google (with several redirects) updates the ACSID and SACSID cookies to the currently logged in user, and redirects back to my application at page B.
  3. Page B finally takes action on behalf of the logged in user, "confident" that the correct user is logged in (to the extent that pages are confident). ;-)

Here's a code sketch of the approach:

# My BaseHandler has a clear_cookie
class LoginAndRedirectHandler(base_handler.BaseHandler):
  def get(self):
    self.clear_cookie('ACSID')
    self.clear_cookie('SACSID')
    self.clear_cookie('dev_appserver_login')

    if 'continue' in self.request.params and \
       self.request.params['continue'].startswith('/'):
      url = self.request.params['continue']
    else:
      # Whatever your page is that needs an up to date logged in user
      url = users.create_login_url('/PageB')

    if isinstance(url, unicode):
      url = url.encode('utf8')
    logging.info('Redirecting to ' + url)
    self.redirect(url)
    return

The reason I said infrequently above is that this process is expensive in time, with at least 4 or 5 redirects involved.

Upvotes: 1

Peter Knego
Peter Knego

Reputation: 80340

Two ways to notify app about user logging out:

  1. Synchronously - server actively notifies client (browser) about log-out. Use Channels API to send push notification to client. There is a GWT wrapper.

  2. Asynchronously - server notifies client about log-out when client makes communication to server, i.e. in every RPC call add authentication check. If user id logged-out, raise an exception, which can be handled by GWT.

Upvotes: 1

Related Questions