Note that there are some explanatory texts on larger screens.

plurals
  1. POTrying to oauth dropbox with Tornado Web
    primarykey
    data
    text
    <p>Here is my mixin file:</p> <pre><code>import base64 import binascii import hashlib import hmac import logging import time import urllib import urlparse import uuid import tornado.web import tornado.auth from tornado import httpclient from tornado import escape from tornado.httputil import url_concat from tornado.util import bytes_type, b class DropboxMixin(tornado.auth.OAuthMixin): """ Dropbox OAuth authentication. """ _OAUTH_REQUEST_TOKEN_URL = "https://api.dropbox.com/1/oauth/request_token" _OAUTH_ACCESS_TOKEN_URL = "https://api.dropbox.com/1/oauth/access_token" _OAUTH_AUTHORIZE_URL = "https://www.dropbox.com/1/oauth/authorize" def authorize_redirect(self, callback_uri=None, extra_params=None, http_client=None): """Redirects the user to obtain OAuth authorization for this service. Twitter and FriendFeed both require that you register a Callback URL with your application. You should call this method to log the user in, and then call get_authenticated_user() in the handler you registered as your Callback URL to complete the authorization process. This method sets a cookie called _oauth_request_token which is subsequently used (and cleared) in get_authenticated_user for security purposes. """ if callback_uri and getattr(self, "_OAUTH_NO_CALLBACKS", False): raise Exception("This service does not support oauth_callback") if http_client is None: http_client = httpclient.AsyncHTTPClient() http_client.fetch( self._oauth_request_token_url(), self.async_callback( self._on_request_token, self._OAUTH_AUTHORIZE_URL, callback_uri)) def get_authenticated_user(self, callback, http_client=None): """Gets the OAuth authorized user and access token on callback. This method should be called from the handler for your registered OAuth Callback URL to complete the registration process. We call callback with the authenticated user, which in addition to standard attributes like 'name' includes the 'access_key' attribute, which contains the OAuth access you can use to make authorized requests to this service on behalf of the user. """ request_key = escape.utf8(self.get_argument("oauth_token")) oauth_verifier = self.get_argument("oauth_verifier", None) request_cookie = self.get_cookie("_oauth_request_token") if not request_cookie: logging.warning("Missing OAuth request token cookie") callback(None) return self.clear_cookie("_oauth_request_token") cookie_key, cookie_secret = [base64.b64decode(escape.utf8(i)) for i in request_cookie.split("|")] if cookie_key != request_key: logging.info((cookie_key, request_key, request_cookie)) logging.warning("Request token does not match cookie") callback(None) return token = dict(key=cookie_key, secret=cookie_secret) if oauth_verifier: token["verifier"] = oauth_verifier if http_client is None: http_client = httpclient.AsyncHTTPClient() http_client.fetch(self._oauth_access_token_url(token), self.async_callback(self._on_access_token, callback)) def dropbox_request(self, path, callback, access_token=None, post_args=None, **args): # Add the OAuth resource request signature if we have credentials url = "http://api.dropbox.com/1" + path </code></pre> <p>If anyone cares the url should read <a href="https://api.dropbox.com/1" rel="nofollow">https://api.dropbox.com/1</a>" + path</p> <pre><code> if access_token: all_args = {} all_args.update(args) all_args.update(post_args or {}) method = "POST" if post_args is not None else "GET" oauth = self._oauth_request_parameters( url, access_token, all_args, method=method) args.update(oauth) if args: url += "?" + urllib.urlencode(args) callback = self.async_callback(self._on_dropbox_request, callback) http = httpclient.AsyncHTTPClient() if post_args is not None: http.fetch(url, method="POST", body=urllib.urlencode(post_args), callback=callback) else: http.fetch(url, callback=callback) def _oauth_request_token_url(self, callback_uri= None, extra_params=None): consumer_token = self._oauth_consumer_token() url = self._OAUTH_REQUEST_TOKEN_URL args = dict( oauth_consumer_key=consumer_token["key"], oauth_signature_method="HMAC-SHA1", oauth_timestamp=str(int(time.time())), oauth_nonce=binascii.b2a_hex(uuid.uuid4().bytes), oauth_version=getattr(self, "_OAUTH_VERSION", "1.0"), ) signature = _oauth_signature(consumer_token, "GET", url, args) args["oauth_signature"] = signature return url + "?" + urllib.urlencode(args) def _oauth_access_token_url(self, request_token): consumer_token = self._oauth_consumer_token() url = self._OAUTH_ACCESS_TOKEN_URL args = dict( oauth_consumer_key=consumer_token["key"], oauth_token=request_token["key"], oauth_signature_method="HMAC-SHA1", oauth_timestamp=str(int(time.time())), oauth_nonce=binascii.b2a_hex(uuid.uuid4().bytes), oauth_version=getattr(self, "_OAUTH_VERSION", "1.0"), ) if "verifier" in request_token: args["oauth_verifier"]=request_token["verifier"] signature = _oauth_signature(consumer_token, "GET", url, args, request_token) args["oauth_signature"] = signature return url + "?" + urllib.urlencode(args) def _on_dropbox_request(self, callback, response): if response.error: print("Error response %s fetching %s", response.error, response.request.url) callback(None) return callback(escape.json_decode(response.body)) def _oauth_consumer_token(self): self.require_setting("dropbox_consumer_key", "Dropbox OAuth") self.require_setting("dropbox_consumer_secret", "Dropbox OAuth") return dict( key=self.settings["dropbox_consumer_key"], secret=self.settings["dropbox_consumer_secret"]) def _oauth_get_user(self, access_token, callback): callback = self.async_callback(self._parse_user_response, callback) self.dropbox_request( "/account/info", access_token=access_token, callback=callback) def _oauth_request_parameters(self, url, access_token, parameters={}, method="GET"): """Returns the OAuth parameters as a dict for the given request. parameters should include all POST arguments and query string arguments that will be sent with the request. """ consumer_token = self._oauth_consumer_token() base_args = dict( oauth_consumer_key=consumer_token["key"], oauth_token=access_token["key"], oauth_signature_method="HMAC-SHA1", oauth_timestamp=str(int(time.time())), oauth_nonce=binascii.b2a_hex(uuid.uuid4().bytes), oauth_version=getattr(self, "_OAUTH_VERSION", "1.0"), ) args = {} args.update(base_args) args.update(parameters) signature = _oauth_signature(consumer_token, method, url, args, access_token) base_args["oauth_signature"] = signature return base_args def _parse_user_response(self, callback, user): if user: user["username"] = user["display_name"] callback(user) def _oauth_signature(consumer_token, method, url, parameters={}, token=None): """Calculates the HMAC-SHA1 OAuth signature for the given request. See http://oauth.net/core/1.0/#signing_process """ parts = urlparse.urlparse(url) scheme, netloc, path = parts[:3] normalized_url = scheme.lower() + "://" + netloc.lower() + path base_elems = [] base_elems.append(method.upper()) base_elems.append(normalized_url) base_elems.append("&amp;".join("%s=%s" % (k, _oauth_escape(str(v))) for k, v in sorted(parameters.items()))) base_string = "&amp;".join(_oauth_escape(e) for e in base_elems) key_elems = [escape.utf8(consumer_token["secret"])] key_elems.append(escape.utf8(token["secret"] if token else "")) key = b("&amp;").join(key_elems) hash = hmac.new(key, escape.utf8(base_string), hashlib.sha1) return binascii.b2a_base64(hash.digest())[:-1] def _oauth_escape(val): if isinstance(val, unicode): val = val.encode("utf-8") return urllib.quote(val, safe="~") def _oauth_parse_response(body): p = escape.parse_qs(body, keep_blank_values=False) token = dict(key=p[b("oauth_token")][0], secret=p[b("oauth_token_secret")][0]) # Add the extra parameters the Provider included to the token special = (b("oauth_token"), b("oauth_token_secret")) token.update((k, p[k][0]) for k in p if k not in special) return token </code></pre> <p>My View</p> <pre><code>class DropboxIndex(BaseHandler, DropboxMixin): @tornado.web.asynchronous def get(self): if self.get_argument("oauth_token", None): self.get_authenticated_user(self.async_callback(self._on_dbox_auth)) return self.authorize_redirect() def _on_dbox_auth(self, token): from pprint import pprint pprint(token) self.redirect("/app/dropbox") </code></pre> <p>My URL Patterns</p> <pre><code>patterns = [ (r"/", Index), (r"/help/?", Help), # User authentication (r"/user/login/?", Login), (r"/user/logout/?", LogoutHandler), (r"/user/edit/?", IdentityIndex), (r"/user/register/?", Register), (r"/user/twitter/auth/?", TwitterLogin), #(r"/user/google/auth/?", GoogleLogin), (r"/user/facebook/auth/?", FacebookLogin), (r"/app/dropbox/?", DropboxIndex), (r"/app/dropbox/account/?", DropboxAccount), (r"/social/?", SocialIndex), (r"/api/tweets/?", apiSocialTweets), (r"/media/(.*)", tornado.web.StaticFileHandler, {"path" : static_serve}), ] </code></pre> <p>Everything works except being brought back to my callback uri with the oauth_token. I see the oauth_token in the query and can authorize my app with dropbox.. i just can't get the oauth_token back and usuable</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload