GAE Bottle Login Handler

While I have my own home-brewed auth system for Herd Hound, there are a couple of situations where I needed to authenticate using Google account. In particular, those are some built-in functionalities like datastore admin, or mapreduce. These things have a built-in interface and they need a way to authenticate users, so they call on the default login handler located at /_ah/login_required. There are many ways to write login handlers (I wouldn’t be surprised if one was included in the SDK, but I didn’t bother to look), and I’ll show you how to do it using the bottle framework.

First you need to add a handler for the /_ah/login_required URL. In your app.yaml file, you need to have these under the handlers: section:

- url: /_ah/login_required
  script: login.py

That’s assuming that login.py file is in the root of your app directory. Adjust the path accordingly relative to your app dir.

Now let’s create the login.py.

#!/usr/bin/env python

from google.appengine.api import users
from bottle import route, request, run, redirect

@route('/_ah/login_required')
def login_required():
    continue_url = request.params.get('continue')
    redirect(users.create_login_url(continue_url))

if __name__ == '__main__':
    run(server='gae')

Will skip the imports. I’m sure you know what they do. One thing to note that, despite of the fact that the mapping in app.yaml has already specified the full path (/_ah/login_required) you still need to duplicate it in your route configuration. Not very nice, but that’s what you need to do.

Every time an built-in component (like mapreduce) hits this URL, it will give you an URL parameter which is an URL to which the app needs to go after login. Using the create_login_url method, you create the Google accounts login URL, which will also have this parameter, and you simply redirect to it.

Yeah, that’s it. Done. Your login handler, sir/madam.