views:

63

answers:

1

Just started playing with Tornado and want to offer multiple methods of authentication. Currently my app is working fine with Google's hybrid OpenID/oAuth using tornado.auth.GoogleMixin and the unauthenticated users are automatically sent to Google's auth page.

If an unauthenticated user wants to use another option (ie. local auth or tornado.auth.TwitterMixin), how can I implement the logic to choose an auth mechanism within the login handler?

I added the decorator 'tornado.web.authenticated' to all of my exposed methods, and here is the my login handler class (pretty much straight from the Tornado examples) which is currently working with Google OpenID/oAuth:

class AuthLoginHandler(BaseHandler, tornado.auth.GoogleMixin):
@tornado.web.asynchronous
def get(self):

    if self.get_argument('openid.mode', None):
        self.get_authenticated_user(self.async_callback(self._on_auth))
        return

    ## redirect after auth
    self.authenticate_redirect()

def _on_auth(self, user):
    ## auth fail
    if not user:
        raise tornado.web.HTTPError(500, 'Google auth failed')

    ## auth success
    identity = self.get_argument('openid.identity', None)

    ## set identity in cookie
    self.set_secure_cookie('identity', tornado.escape.json_encode(identity))
    self.redirect('/')

Appreciate any suggestions for a solution. Thanks

+2  A: 

I think the easiest way to do it would be to change the AuthLoginHandler to something more specific, like GoogleAuthHandler, and create an appropriate route for that:

(r"/login/google/", GoogleAuthHandler),
(r"/login/facebook/", FacebookAuthHandler),

etc.

Then simply create links to each authentication provider on the page ala:

<a href="/login/google/>Login with Google</a>
<a href="/login/facebook/">Login with Facebook</a>

If you wanted to make it fancier, you could provide the providers as a select box, or if you wanted to get REALLY fancy, you could parse their 'openid' URL (e.g., if username.google.com, self.redirect("/login/google"), but that assumes that users know their OpenID provider URLs, which is usually not the case. I'd guess if you gave them a google / facebook / twitter icon or something to click on that would confuse the least number of people.

bmelton
Thanks for the help.
joet3ch