Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Cloud Endpoints authentication using webapp2 sessions

The client of my Google Cloud Endpoints API is an JavaScript (AngularJS) web application hosted on the same Google App Engine application as the Endpoints API itself. My users authenticate using webapp2 sessions (datastore). They don't necessarily have a Google account. I want to be able to do a request to the Endpoints API like /api/users/me which would return the user data of the user who is currently logged in.

First I thought I had to implement a OAuth2 provider for my App Engine application, and then let the AngularJS application request a OAuth2 access token from my own App Engine OAuth provider (instead of the OAuth provider of Google, like the built in authentication mechanism does).

However, this comment suggests not implementing my own OAuth2 provider but instead providing arbitrary parameters in my request (in a message field, or in a HTTP header) to the Endpoints API. I guess that parameter should be a user token (some encrypted value unique to the logged in user?). That value should then be passed to the browser. Isn't that insecure? I would like not to serve my AngularJS application on HTTPS if possible (to save costs).

Is this a good use case for OAuth2? Or is OAuth2 only for granting third party applications access to user data?

In case OAuth2 is not the way to go: how to pass a user token securily to the browser and prevent man-in-the-middle attacks? Should the user token expire after a certain amount of time?

like image 366
Korneel Avatar asked Dec 19 '13 14:12

Korneel


1 Answers

I've just finished implementing exactly what you've described. Basically this method does the trick:

def get_current_session(request_state):
    cookies = werkzeug.http.parse_cookie(request_state.headers.get('Cookie'))
    sess_cookie = cookies.get('mc_session')
    parts = sess_cookie.split('|')
    if len(parts) != 3:
        logging.error('Cookie does not have 3 parts')
        return False

    signature = hmac.new(COOKIE_SECRET_KEY, digestmod=hashlib.sha1)
    signature.update('|'.join(parts))
    sig_hex = signature.hexdigest()
    if compare_hashes(sig_hex, parts[2]):
        logging.error('Cookie signature mismatch!')
        return False

    cookie_data = webapp2_extras.json.b64decode(parts[0])
    return sessions_ndb.Session.get_by_sid(cookie_data['_sid'])

And you'd call that from your API method using:

session = get_current_session(self.request_state)

You can find all the details at: https://blog.artooro.com/2014/08/21/share-sessions-between-google-cloud-endpoints-and-webapp2/

like image 107
artooro Avatar answered Sep 30 '22 02:09

artooro