I recently started a project using python-tornado, and needed to implement google OAuth to manage user logins. I struggled getting this working in the context of the project, and decided to abstract it out to a simple working demo. Since it was such a bear to get up and running in the first place, I wanted to seek feedback regarding my specific implementation, to have the best fleshed-out boilerplate I can to quickly get a new project up and running. Any advice regarding performance/security/maintainability are greatly appreciated.

Below is the code, which a working demo can be found on Github.

import os
import tornado.auth
import tornado.autoreload
import tornado.ioloop
import tornado.web
import json

class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("user")

class TestHandler(BaseHandler):
    def get(self):
        name = tornado.escape.xhtml_escape(self.current_user)
        print self.get_current_user()
        self.write("Hello, " + name)

class MainHandler(BaseHandler):
    def get(self):
        if not self.current_user:

class GoogleOAuth2LoginHandler(BaseHandler, tornado.auth.GoogleOAuth2Mixin):
    def get(self):
        if self.get_argument('code', False):
            access = yield self.get_authenticated_user(
            user = yield self.oauth2_request("https://www.googleapis.com/oauth2/v1/userinfo", access_token=access["access_token"])
            self.set_secure_cookie("user", json.dumps(user))
            self.current_user = user
            yield self.authorize_redirect(
            scope=['profile', 'email'],
            extra_params={'approval_prompt': 'auto'}

def make_app():
    settings = {
    'google_oauth' : {
            'key': os.environ['CLIENT_ID'],
            'secret': os.environ['CLIENT_SECRET'],
    'redirect_uri': os.environ['REDIRECT_URI'],
    'login_url': '/',
    'cookie_secret': os.environ['COOKIE_SECRET']
    return tornado.web.Application([
        (r"/", GoogleOAuth2LoginHandler),
        (r"/test", TestHandler)], **settings)

if __name__ == "__main__":
    app = make_app()
    print "Listening on port 8888"
    for dir, _, files in os.walk('./'):
        [tornado.autoreload.watch(dir + '/' + f) for f in files if not f.startswith('.')]

  • \$\begingroup\$ Your indentation seems off at several places. Can you check that the code is displayed exactly like in your editor and edit in the differences, please. \$\endgroup\$ – 301_Moved_Permanently Dec 10 '17 at 13:59
  • \$\begingroup\$ Thank you, it was just the one method from a bad copy and paste. I updated it to reflect the correct spacing. \$\endgroup\$ – Justin Olson Dec 11 '17 at 19:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.