Codeception

Musings & ramblings of a Pythonista

Custom Authentication for Google App Engine apps

Google App Engine

Google App Engine is a widely used and most popular PaaS solution provided by Google. App Engine provides the developer with a wide range of apis which can be used to develop web applications using any WSGI compliant Frameworks (Webapp, Tipfy, Django, Bottle, Tornado etc.). One of the apis App Engine provides is the users api, which most of the developers confuses for an api which provides user creation, authentication for the application. But this api only authenticates Google Accounts (can be the application developer or any third-party Google Account) using OAuth. You can't really user this api to create or manage users for your application.

Remember when I told you that every application you write for GAE is a WSGI Application? WSGI is just a standard for the web application to talk to the backend HTTP server. That means a WSGI application can't run by itself. It needs an HTTP server to listen on and execute the code you have written. Its the HTTP Server which handles all the server stuffs used for authentication such as setting cookies. Now, GAE has a sandbox, which is a restrictive environment for your application code to run. For example, your application is restricted for file operations and certain modules are restricted from importing. So you can't really set up a cookie from your application code since its not an HTTP Server code. Here is our problem now. How do you do a custom authentication for a Google App Engine application?

You can achieve this by writing a middleware to your WSGI application. There are many authentication libraries available for this purpose. Popular ones are Beaker, GAE-Sessions, gaeutilities. But I liked the GAE-Sessions library better than the other ones since its the fastest of them all. GAE-Sessions use memcache/datastore to store the session information. To use this library, just copy the gaesessions directory to your application directory. The middleware for your application is as simple as shown in the code below

from gaesessions import SessionMiddleware
def webapp_add_wsgi_middleware(app):
    app = SessionMiddleware(app, cookie_key="a random and long string")
    return app

Save the above code to a file named appengine_config.py. You can use gaesessions.get_current_session() to get a dictionary to store all the session information. You can either use session.set_quick(<session-var>, <value>) method to use application memcache for storing session info. Otherwise it'll be stored to the datastore. Getting session info is as easy as session.get(<session-var>) and session.pop_quick(<session-var>) will remove the information from the session. All the dictionary like indexed operations will be persisted to the database.

from gaesessions import get_current_session
session = get_current_session()

# setting user session information
session.set_quick('user', 'authenticated_user_info')
# getting user session
user = session.get('user')
# removing session info
session.pop_quick('user')

The default session lifetime is 7 days. You may configure how long a session lasts by calling SessionMiddleware with a lifetime parameter, e.g., lifetime=datetime.timedelta(hours=2)). You can schedule a cron job for cleaning up all the expired session info for your application by creating a handler file like this.

# cleanup_sessions.py
from gaesessions import delete_expired_sessions
while not delete_expired_sessions():
    pass

Make sure you have a cron.yaml with the correct info.

cron:
- description: daily session cleanup
  url: /cleanup_sessions
  schedule: every 24 hours

You can find a complete sample application here.

Tagged under Python, Tips, App Engine, GAESessions

blog comments powered by Disqus