Python Tornado身份验证(Twittermixin)问题
我目前正在尝试使用tornado来显示我的twitter流。下面是我的代码:Python Tornado身份验证(Twittermixin)问题,python,oauth,tornado,Python,Oauth,Tornado,我目前正在尝试使用tornado来显示我的twitter流。下面是我的代码: #!/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.o
#!/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\u url
2.)访问'/login'-LoginHandler,self.authorize\u重定向(callback\u uri=self.request.full\u url())
将在url末尾附加oauth\u令牌参数,然后重新访问'/login'
3.)访问'/login'-LoginHandler,从self.get\u authenticated\u user()
获取用户,并set\u secure\u cookie(self.cookie\u NAME,json\u encode(user))
我想这就是问题所在,我似乎无法设置cookie。当我试图通过self.get\u secure\u cookie(self.cookie\u NAME)
立即访问它时,它返回None
,因此它会继续重新访问“/login”
有人能帮我解决这个问题吗?也许这是很明显我没有看到的东西。谢谢
我还设置了http://127.0.0.1:8080/
作为我的twitter应用程序设置上的回调url,不确定这是否与问题有关。最终解决方案
#!/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()
好的,我确信
set\u secure\u cookie(name=self.cookie\u name,value=json\u encode(user))
是问题的原因,它从未在我的浏览器上设置cookie。我已经检查了user
对象是否存在,并且它是dict
,并且json\u encode
确实返回字符串值…因此肯定有set\u secure\u cookie
函数。。。。