tornado.auth — Third-party login with OpenID and OAuth¶

This module contains implementations of various third-partyauthentication schemes.

All the classes in this file are class mixins designed to be used withthe tornado.web.RequestHandler class. They are used in two ways:

  • On a login handler, use methods such as authenticate_redirect(),authorize_redirect(), and get_authenticated_user() toestablish the user’s identity and store authentication tokens to yourdatabase and/or cookies.
  • In non-login handlers, use methods such as facebook_request()or twitter_request() to use the authentication tokens to makerequests to the respective services.
    They all take slightly different arguments due to the fact all theseservices implement authentication and authorization slightly differently.See the individual service classes below for complete documentation.

Example usage for Google OAuth:

  1. class GoogleOAuth2LoginHandler(tornado.web.RequestHandler,
  2. tornado.auth.GoogleOAuth2Mixin):
  3. @tornado.gen.coroutine
  4. def get(self):
  5. if self.get_argument('code', False):
  6. user = yield self.get_authenticated_user(
  7. redirect_uri='http://your.site.com/auth/google',
  8. code=self.get_argument('code'))
  9. # Save the user with e.g. set_secure_cookie
  10. else:
  11. yield self.authorize_redirect(
  12. redirect_uri='http://your.site.com/auth/google',
  13. client_id=self.settings['google_oauth']['key'],
  14. scope=['profile', 'email'],
  15. response_type='code',
  16. extra_params={'approval_prompt': 'auto'})

在 4.0 版更改: All of the callback interfaces in this module are now guaranteedto run their callback with an argument of None on error.Previously some functions would do this while others would simplyterminate the request on their own. This change also ensures thaterrors are more consistently reported through the Future interfaces.

Common protocols¶

These classes implement the OpenID and OAuth standards. They willgenerally need to be subclassed to use them with any particular site.The degree of customization required will vary, but in most casesoverridding the class attributes (which are named beginning withunderscores for historical reasons) should be sufficient.

class tornado.auth.OpenIdMixin[源代码]

Abstract implementation of OpenID and Attribute Exchange.

Class attributes:

- OPENID_ENDPOINT: the identity provider’s URI.
authenticate_redirect(args, **kwargs)[源代码]

Redirects to the authentication URL for this service.

After authentication, the service will redirect back to the givencallback URI with additional parameters including openid.mode.

We request the given attributes for the authenticated user bydefault (name, email, language, and username). If you don’t needall those attributes for your app, you can request fewer withthe ax_attrs keyword argument.


在 3.1 版更改: Returns a Future and takes an optional callback. These arenot strictly necessary as this method is synchronous,but they are supplied for consistency withOAuthMixin.authorize_redirect.

get_authenticated_user(args, kwargs)[源代码]

Fetches the authenticated user data upon redirect.

This method should be called by the handler that receives theredirect from the authenticate_redirect() method (which isoften the same as the one that calls it; in that case you wouldcall get_authenticated_user if the openid.mode parameteris present and authenticate_redirect if it is not).

The result of this method will generally be used to set a cookie.
get_auth_http_client()[源代码]

Returns the AsyncHTTPClient instance to be used for auth requests.

May be overridden by subclasses to use an HTTP client other thanthe default.
_class tornado.auth.OAuthMixin[源代码]

Abstract implementation of OAuth 1.0 and 1.0a.

See TwitterMixin below for an example implementation.

Class attributes:

- OAUTH_AUTHORIZE_URL: The service’s OAuth authorization url.
- _OAUTH_ACCESS_TOKEN_URL: The service’s OAuth access token url.
- _OAUTH_VERSION: May be either “1.0” or “1.0a”.
- _OAUTH_NO_CALLBACKS: Set this to True if the service requiresadvance registration of callbacks.
Subclasses must also override the _oauth_get_user_future and_oauth_consumer_token methods.
authorize_redirect(*args, kwargs)[源代码]

Redirects the user to obtain OAuth authorization for this service.

The callback_uri may be omitted if you have previouslyregistered a callback URI with the third-party service. Forsome services (including Friendfeed), you must use apreviously-registered callback URI and cannot specify acallback via this method.

This method sets a cookie called _oauth_request_token which issubsequently used (and cleared) in get_authenticated_user forsecurity purposes.

Note that this method is asynchronous, although it callsRequestHandler.finish for you so it may not be necessaryto pass a callback or use the Future it returns. However,if this method is called from a function decorated withgen.coroutine, you must call it with yield to keep theresponse from being closed prematurely.


在 3.1 版更改: Now returns a Future and takes an optional callback, forcompatibility with gen.coroutine.

get_authenticated_user(args, **kwargs)[源代码]

Gets the OAuth authorized user and access token.

This method should be called from the handler for yourOAuth callback URL to complete the registration process. We run thecallback with the authenticated user dictionary. This dictionarywill contain an access_key which can be used to make authorizedrequests to this service on behalf of the user. The dictionary willalso contain other fields such as name, depending on the serviceused.
_oauth_consumer_token()[源代码]

Subclasses must override this to return their OAuth consumer keys.

The return value should be a dict with keys key and secret.
_oauth_get_user_future(args, kwargs)[源代码]

Subclasses must override this to get basic information about theuser.

Should return a Future whose result is a dictionarycontaining information about the user, which may have beenretrieved by using access_token to make a request to theservice.

The access token will be added to the returned dictionary to makethe result of get_authenticated_user.

For backwards compatibility, the callback-based _oauth_get_usermethod is also supported.
get_auth_http_client()[源代码]

Returns the AsyncHTTPClient instance to be used for auth requests.

May be overridden by subclasses to use an HTTP client other thanthe default.
_class tornado.auth.OAuth2Mixin[源代码]

Abstract implementation of OAuth 2.0.

See FacebookGraphMixin or GoogleOAuth2Mixin below for exampleimplementations.

Class attributes:

- OAUTH_AUTHORIZE_URL: The service’s authorization url.
- _OAUTH_ACCESS_TOKEN_URL: The service’s access token url.
authorize_redirect(*args, kwargs)[源代码]

Redirects the user to obtain OAuth authorization for this service.

Some providers require that you register a redirect URL withyour application instead of passing one via this method. Youshould call this method to log the user in, and then callget_authenticated_user in the handler for yourredirect URL to complete the authorization process.


在 3.1 版更改: Returns a Future and takes an optional callback. These arenot strictly necessary as this method is synchronous,but they are supplied for consistency withOAuthMixin.authorize_redirect.

oauth2_request(args, *kwargs_)[源代码]

Fetches the given URL auth an OAuth2 access token.

If the request is a POST, post_args should be provided. Querystring arguments should be given as keyword arguments.

Example usage:

..testcode:



  1. class MainHandler(tornado.web.RequestHandler,
    tornado.auth.FacebookGraphMixin):
    @tornado.web.authenticated
    @tornado.gen.coroutine
    def get(self):
    new_entry = yield self.oauth2_request(
    "https://graph.facebook.com/me/feed",
    post_args={"message": "I am posting from my Tornado application!"},
    access_token=self.current_user["access_token"])

    if not new_entry:
    # Call failed; perhaps missing permission?
    yield self.authorize_redirect()
    return
    self.finish("Posted a message!")





4.3 新版功能.

get_auth_http_client()[源代码]

Returns the AsyncHTTPClient instance to be used for auth requests.

May be overridden by subclasses to use an HTTP client other thanthe default.


4.3 新版功能.

Google¶

class tornado.auth.GoogleOAuth2Mixin[源代码]

Google authentication using OAuth2.

In order to use, register your application with Google and copy therelevant parameters to your application settings.

- Go to the Google Dev Console at http://console.developers.google.com
- Select a project, or create a new one.
- In the sidebar on the left, select APIs & Auth.
- In the list of APIs, find the Google+ API service and set it to ON.
- In the sidebar on the left, select Credentials.
- In the OAuth section of the page, select Create New Client ID.
- Set the Redirect URI to point to your auth handler
- Copy the “Client secret” and “Client ID” to the application settings as{“googleoauth”: {“key”: CLIENT_ID, “secret”: CLIENT_SECRET}}

3.2 新版功能.

get_authenticated_user(args, *kwargs_)[源代码]

Handles the login for the Google user, returning an access token.

The result is a dictionary containing an access_token field(among others)).Unlike other get_authenticated_user methods in this package,this method does not return any additional information about the user.The returned access token can be used with OAuth2Mixin.oauth2_requestto request additional information (perhaps fromhttps://www.googleapis.com/oauth2/v2/userinfo)

Example usage:



  1. class GoogleOAuth2LoginHandler(tornado.web.RequestHandler,
    tornado.auth.GoogleOAuth2Mixin):
    @tornado.gen.coroutine
    def get(self):
    if self.get_argument('code', False):
    access = yield self.get_authenticated_user(
    redirect_uri='http://your.site.com/auth/google',
    code=self.get_argument('code'))
    user = yield self.oauth2_request(
    "https://www.googleapis.com/oauth2/v1/userinfo",
    access_token=access["access_token"])
    # Save the user and access token with
    # e.g. set_secure_cookie.
    else:
    yield self.authorize_redirect(
    redirect_uri='http://your.site.com/auth/google',
    client_id=self.settings['google_oauth']['key'],
    scope=['profile', 'email'],
    response_type='code',
    extra_params={'approval_prompt': 'auto'})



Facebook¶

class tornado.auth.FacebookGraphMixin[源代码]

Facebook authentication using the new Graph API and OAuth2.
getauthenticated_user(args, **kwargs)[源代码]

Handles the login for the Facebook user, returning a user object.

Example usage:



  1. class FacebookGraphLoginHandler(tornado.web.RequestHandler,
    tornado.auth.FacebookGraphMixin):
    @tornado.gen.coroutine
    def get(self):
    if self.get_argument("code", False):
    user = yield self.get_authenticated_user(
    redirect_uri='/auth/facebookgraph/',
    client_id=self.settings["facebook_api_key"],
    client_secret=self.settings["facebook_secret"],
    code=self.get_argument("code"))
    # Save the user with e.g. set_secure_cookie
    else:
    yield self.authorize_redirect(
    redirect_uri='/auth/facebookgraph/',
    client_id=self.settings["facebook_api_key"],
    extra_params={"scope": "read_stream,offline_access"})



facebook_request(args, **kwargs_)[源代码]

Fetches the given relative API path, e.g., “/btaylor/picture”

If the request is a POST, post_args should be provided. Querystring arguments should be given as keyword arguments.

An introduction to the Facebook Graph API can be found athttp://developers.facebook.com/docs/api

Many methods require an OAuth access token which you canobtain through authorize_redirect andget_authenticated_user. The user returned through thatprocess includes an access_token attribute that can beused to make authenticated requests via this method.

Example usage:

..testcode:



  1. class MainHandler(tornado.web.RequestHandler,
    tornado.auth.FacebookGraphMixin):
    @tornado.web.authenticated
    @tornado.gen.coroutine
    def get(self):
    new_entry = yield self.facebook_request(
    "/me/feed",
    post_args={"message": "I am posting from my Tornado application!"},
    access_token=self.current_user["access_token"])

    if not new_entry:
    # Call failed; perhaps missing permission?
    yield self.authorize_redirect()
    return
    self.finish("Posted a message!")




The given path is relative to self._FACEBOOK_BASE_URL,by default “https://graph.facebook.com”.

This method is a wrapper around OAuth2Mixin.oauth2_request;the only difference is that this method takes a relative path,while oauth2_request takes a complete url.


在 3.1 版更改: Added the ability to override self._FACEBOOK_BASE_URL.

Twitter¶

class tornado.auth.TwitterMixin[源代码]

Twitter OAuth authentication.

To authenticate with Twitter, register your application withTwitter at http://twitter.com/apps. Then copy your Consumer Keyand Consumer Secret to the applicationsettings twitterconsumer_key andtwitter_consumer_secret. Use this mixin on the handler for theURL you registered as your application’s callback URL.

When your application is set up, you can use this mixin like thisto authenticate the user with Twitter and get access to their stream:



  1. class TwitterLoginHandler(tornado.web.RequestHandler,
    tornado.auth.TwitterMixin):
    @tornado.gen.coroutine
    def get(self):
    if self.get_argument("oauth_token", None):
    user = yield self.get_authenticated_user()
    # Save the user using e.g. set_secure_cookie()
    else:
    yield self.authorize_redirect()




The user object returned by get_authenticated_userincludes the attributes username, name, access_token,and all of the custom Twitter user attributes described athttps://dev.twitter.com/docs/api/1.1/get/users/show
authenticate_redirect(args, **kwargs)[源代码]

Just like authorize_redirect, butauto-redirects if authorized.

This is generally the right interface to use if you are usingTwitter for single-sign on.


在 3.1 版更改: Now returns a Future and takes an optional callback, forcompatibility with gen.coroutine.

twitter_request(args, **kwargs_)[源代码]

Fetches the given API path, e.g., statuses/user_timeline/btaylor

The path should not include the format or API version number.(we automatically use JSON format and API version 1).

If the request is a POST, post_args should be provided. Querystring arguments should be given as keyword arguments.

All the Twitter methods are documented at http://dev.twitter.com/

Many methods require an OAuth access token which you canobtain through authorize_redirect andget_authenticated_user. The user returned through thatprocess includes an ‘access_token’ attribute that can be usedto make authenticated requests via this method. Exampleusage:



  1. class MainHandler(tornado.web.RequestHandler,
    tornado.auth.TwitterMixin):
    @tornado.web.authenticated
    @tornado.gen.coroutine
    def get(self):
    new_entry = yield self.twitter_request(
    "/statuses/update",
    post_args={"status": "Testing Tornado Web Server"},
    access_token=self.current_user["access_token"])
    if not new_entry:
    # Call failed; perhaps missing permission?
    yield self.authorize_redirect()
    return
    self.finish("Posted a message!")



原文:

https://tornado-zh-cn.readthedocs.io/zh_CN/latest/auth.html