2015-12-22 2 views
-1

В настоящее время я пытаюсь использовать торнадо для отображения моих твиттер-потоков. Ниже мой код:Tornado Auth (Twittermixin) issue

#!/usr/bin/env python 
import time 
import logging 
from tornado.auth import TwitterMixin 
from tornado.escape import json_decode, json_encode 
from tornado.ioloop import IOLoop 
from tornado import gen 
from tornado.options import define, options, parse_command_line, parse_config_file 
from tornado.web import Application, RequestHandler, authenticated, HTTPError 

define('port', default=8080, help="port to listen on") 
define('config_file', default='secrets.cfg', 
     help='filename for additional configuration') 

define('debug', default=True, group='application', 
     help="run in debug mode (with automatic reloading)") 
# The following settings should probably be defined in secrets.cfg 
define('twitter_consumer_key', type=str, group='application') 
define('twitter_consumer_secret', type=str, group='application') 
define('cookie_secret', type=str, group='application', 
     default='this is a string', 
     help="signing key for secure cookies") 

class BaseHandler(RequestHandler): 
    COOKIE_NAME = "uuser" 
    def get_current_user(self): 
     user_json = self.get_secure_cookie(self.COOKIE_NAME) 
     if not user_json: 
      print(" No user_json") 
      return None 
     print(" Yes user_json") 
     return json_decode(user_json) 

class MainHandler(BaseHandler, TwitterMixin): 
    @authenticated 
    @gen.coroutine 
    def get(self): 
     timeline = yield self.twitter_request(
      '/statuses/home_timeline', 
      access_token = self.current_user['access_token']) 
     self.render('home.html', timeline=timeline) 

class LoginHandler(BaseHandler, TwitterMixin): 
    @gen.coroutine 
    def get(self): 
     if self.get_argument('oauth_token', None): 
      user = yield self.get_authenticated_user() 
      print(' user:', type(user)) 
      del user["description"] 
      self.set_secure_cookie(self.COOKIE_NAME, json_encode(user)) 
      print(' get_secure_cookie:', self.get_secure_cookie(self.COOKIE_NAME)) 
      self.redirect(self.get_argument('next', '/')) 
     else: 
      print(" Authorize_redirecting...") 
      yield self.authorize_redirect(callback_uri=self.request.full_url()) 

class LogoutHandler(BaseHandler): 
    def get(self): 
     self.clear_cookie("user") 

def main(): 
    parse_command_line(final=False) 
    parse_config_file(options.config_file) 

    app = Application(
     [ 
      (r'/', MainHandler), 
      (r'/login', LoginHandler), 
      (r'/logout', LogoutHandler), 
     ], 
     login_url='/login', 
     **options.group_dict('application')) 
    app.listen(options.port) 

    logging.info('Listening on http://localhost:%d' % options.port) 
    IOLoop.current().start() 

if __name__ == '__main__': 
    main() 

Так что мое понимание потока следующим образом:

1.) Визит «/» - MainHandler, то @authenticated будет перенаправлять login_url, если пользователь не вошел в систему.

2.) посещение '/ Войти' - LoginHandler, self.authorize_redirect(callback_uri=self.request.full_url()) добавит oauth_token аргумент в конце URL, и повторное посещение '/ Войти'

3.) визит '/ Войти' - LoginHandler, получим пользователя от self.get_authenticated_user() и set_secure_cookie(self.COOKIE_NAME, json_encode(user))

И вот проблема, я думаю, я не могу настроить cookie. Когда я пытаюсь получить к нему доступ немедленно self.get_secure_cookie(self.COOKIE_NAME), он возвращает None, и, следовательно, он продолжает повторное посещение '/ login'

Может ли кто-нибудь помочь моей проблеме? Может быть, это нечто очевидное, чего я не вижу. Спасибо

Я также установил http://127.0.0.1:8080/ в качестве URL-адреса обратного вызова в настройках моего Twitter-приложения, не уверен, что это имеет какой-либо вклад в проблему.

+0

Хорошо, я уверен, что 'set_secure_cookie (имя = self.COOKIE_NAME, значение = json_encode (пользователь))' является причиной проблемы, он никогда не удается установить куки на моем браузере. Я проверил объект 'user' и существует' dict', а 'json_encode' возвращает строковое значение ... поэтому должно быть что-то с функцией set_secure_cookie. – creampiedonut

ответ

-2

Окончательное решение!

#!/usr/bin/env python 
import time 
import uuid 
import logging 
from tornado.auth import TwitterMixin 
from tornado.escape import json_decode, json_encode, url_escape, url_unescape 
from tornado.ioloop import IOLoop 
from tornado import gen 
from tornado.options import define, options, parse_command_line, parse_config_file 
from tornado.web import Application, RequestHandler, authenticated, HTTPError 
from urllib.parse import quote 
import re 

define('port', default=8080, help="port to listen on") 
define('config_file', default='secrets.cfg', 
     help='filename for additional configuration') 

define('debug', default=True, group='application', 
     help="run in debug mode (with automatic reloading)") 
# The following settings should probably be defined in secrets.cfg 
define('twitter_consumer_key', type=str, group='application') 
define('twitter_consumer_secret', type=str, group='application') 
# define('cookie_secret', type=str, group='application', 
#  default='thisisastring', 
#  help="signing key for secure cookies") 


class BaseHandler(RequestHandler): 
    COOKIE_NAME = "user" 
    def get_current_user(self): 
     user_json = self.get_cookie(self.COOKIE_NAME) 
     if not user_json: 
      print("\n - Cannot obtain cookie from client browser") 
      return None 
     print("\n - Cookie obtained from client browser") 
     return json_decode(user_json) 

class MainHandler(BaseHandler, TwitterMixin): 
    @authenticated 
    @gen.coroutine 
    def get(self): 
     print("\n - Obtaining timeline from twitter") 
     timeline = yield self.twitter_request(
      '/statuses/home_timeline', 
      access_token = self.current_user) 
     self.render('home.html', timeline=timeline) 

class LoginHandler(BaseHandler, TwitterMixin): 
    @gen.coroutine 
    def get(self): 
     if self.get_argument('oauth_token', None): 
      print("\n - Authenticating with oauth_token...") 
      user = yield self.get_authenticated_user() 
      encoded_token = json_encode(user['access_token']) 

      # remove certain ascii symbols which are rejected 
      # by self.set_cookie() function... 
      encoded_token = re.sub(r"[\x00-\x20]", '', encoded_token) 

      # save encoded token as cookie 
      self.set_cookie(name=self.COOKIE_NAME, value=encoded_token) 
      self.redirect(self.get_argument('next', '/')) 
     else: 
      print("\n - Authorize_redirecting...") 
      yield self.authorize_redirect(callback_uri=self.request.full_url()) 

class LogoutHandler(BaseHandler): 
    def get(self): 
     self.clear_cookie(self.COOKIE_NAME) 

def main(): 
    parse_command_line(final=False) 
    parse_config_file(options.config_file) 

    app = Application(
     [ 
      (r'/', MainHandler), 
      (r'/login', LoginHandler), 
      (r'/logout', LogoutHandler), 
     ], 
     login_url='/login', 
     cookie_secret=str(uuid.uuid4().bytes), 
     **options.group_dict('application')) 
    app.listen(options.port) 

    logging.info('Listening on http://localhost:%d' % options.port) 
    IOLoop.current().start() 

if __name__ == '__main__': 
    main()