You might have observed and experienced so many Website or Web APIs that let authenticate an user with their Google, Facebook or Twitter accounts. Well, this possible because of third party authentication (or a concept that I like referring as ‘Authentication As A Service’). With the open standards (also referred as protocols) authentication like OpenID and OAuth (latest being OAuth2), authentication can treated as an independent entity apart from services a web API or Website provides. Not only does it eschews the users from creating login accounts for all websites but also the website developer’s effort in proving authentication service is saved.
OpenID and OAuth provides a framework in which users can register with OpenID provider (like Google) or OAuth provider (like Github, Facebook) and then use Google or Facebook accounts to login to other sites that provide third party authentication. As a web developer providing third party authentication requires you to create a web application with the service providers. For instance, using OAuth2 authentication of Facebook, requires you to register your app (for API Key and Application Secret) with Facebook at their developers page. Google provides both OpenID and OAuth authentication, but registration is not required…
Web application based on Tornado can leverage these open standards for authenticating a user with help of Tornado’s abstraction for OpenID and OAuth with tornado.auth.OpenIDMixin, tornado.auth.OAuthMixin and tornado.auth.OAuth2Mixin. Methods that are used by these classes are
- authenticate_redirect(), authorize_redirect(): To redirect the user to appropriate service providers authentication page and
- get_authenticated_user(): To get the user information as provided by service provider
Tornado also provides abstraction for authenticating users with Facebook, Twitter with tornado.auth.FacebookMixin (Facebook OAuth authentication) and tornado.auth.TwitterMixin (Twitter OAuth authentication) and tornado.auth.GoogleMixin (works for both Google OpenID and OAuth authentication).
Let’s understand more with an example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import tornado.auth | |
import tornado.escape | |
import tornado.httpserver | |
import tornado.ioloop | |
import tornado.web | |
class BaseHandler(tornado.web.RequestHandler): | |
def get_current_user(self): | |
user_json = self.get_secure_cookie("user") | |
return tornado.escape.json_decode(user_json) | |
class MainHandler(BaseHandler): | |
@tornado.web.authenticated | |
def get(self): | |
name = tornado.escape.xhtml_escape(self.current_user["name"]) | |
self.write("Hello, " + name) | |
class AuthHandler(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 | |
self.authenticate_redirect() | |
def _on_auth(self, user): | |
if not user: | |
self.send_error(500) | |
self.set_secure_cookie("user", tornado.escape.json_encode(user)) | |
self.redirect("/") | |
application = tornado.web.Application([ | |
(r"/", MainHandler), | |
(r"/login", AuthHandler)], | |
cookie_secret="32oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", | |
login_url="/login", | |
) | |
if __name__ == '__main__': | |
application.listen(9000) | |
tornado.ioloop.IOLoop.instance().start() |
Above example is similar to one we used for Tornado – Authentication blog.. It’s important note the usage of self.get_argument(“openid.mode”) – which signifies using OpenID Authentication.
Very true most of the websites uses twitter, facebook and google and not openid which I preferred using most of the time when commenting. Especially that I use keywords for my websites such as grovespot.com the best bar, restaurant cafe in miami. Thisu helps me better than logging in through different accounts. Thank you for such a great article.