把 Tornado 升级到4后,发现正常运行的微博登录不可以了。

原因是4已经移除 RequestHandler.async_callback and WebSocketHandler.async_callback ,具体见 http://www.tornadoweb.org/en/stable/releases/v4.0.0.html

替换成 functools.partial 就可解决

记得需要先

import functools

修改后的Weibo.py如下

# -*- coding: utf-8 -*-
import functools
from tornado import gen
from tornado import httpclient
from tornado import escape
from tornado.httputil import url_concat
from tornado.concurrent import Future
from tornado.auth import OAuth2Mixin, _auth_return_future, AuthError try:
import urlparse
except ImportError:
import urllib.parse as urlparse try:
import urllib.parse as urllib_parse
except ImportError:
import urllib as urllib_parse class WeiboMixin(OAuth2Mixin):
_OAUTH_ACCESS_TOKEN_URL = 'https://api.weibo.com/oauth2/access_token'
_OAUTH_AUTHORIZE_URL = 'https://api.weibo.com/oauth2/authorize?' @_auth_return_future
def get_authenticated_user(self, redirect_uri, client_id, client_secret, code, callback, grant_type='authorization_code', extra_fields=None):
http = self.get_auth_http_client()
args = {
'redirect_uri': redirect_uri,
'code': code,
'client_id': client_id,
'client_secret': client_secret,
'grant_type': grant_type,
} fields = set(['id', 'screen_name', 'profile_image_url']) if extra_fields:
fields.update(extra_fields) # self.async_callback
http.fetch(self._OAUTH_ACCESS_TOKEN_URL, method='POST',
body=urllib_parse.urlencode(args),
callback=functools.partial(self._on_access_token, redirect_uri, client_id, client_secret, callback, fields)) def _oauth_request_token_url(self, redirect_uri=None, client_id=None,
client_secret=None, code=None,
grant_type=None, extra_params=None):
pass def _on_access_token(self, redirect_uri, client_id, client_secret,
future, fields, response):
if response.error:
future.set_exception(AuthError('Weibo auth error %s' % str(response)))
return args = escape.json_decode(escape.native_str(response.body))
session = {
'access_token': args['access_token'],
'expires': args['expires_in'],
'uid': args['uid'],
} # self.async_callback
self.weibo_request(
path='/users/show.json',
callback=functools.partial(
self._on_get_user_info, future, session, fields),
access_token=session['access_token'],
uid=session['uid']
) def _on_get_user_info(self, future, session, fields, user):
if user is None:
future.set_result(None)
return fieldmap = {}
for field in fields:
fieldmap[field] = user.get(field) fieldmap.update({'access_token': session['access_token'], 'session_expires': session['expires']}) future.set_result(fieldmap) @_auth_return_future
def weibo_request(self, path, callback, access_token=None, uid=None, post_args=None, **args):
url = "https://api.weibo.com/2" + path
all_args = {}
if access_token:
all_args['access_token'] = access_token
if uid:
all_args['uid'] = uid
if args:
all_args.update(args) if all_args:
url += '?' + urllib_parse.urlencode(all_args)
# self.async_callback
callback = functools.partial(self._on_weibo_request, callback)
http = self.get_auth_http_client()
if post_args is not None:
http.fetch(url, method="POST", body=urllib_parse.urlencode(post_args),
callback=callback)
else:
http.fetch(url, callback=callback) def _on_weibo_request(self, future, response):
if response.error:
future.set_exception(AuthError('Error response %s fetching %s',
response.error, response.request.url)) return future.set_result(escape.json_decode(response.body)) def get_auth_http_client(self):
return httpclient.AsyncHTTPClient()

登录代码

class WeiboAuthHandler(SNSBaseHandler, WeiboMixin):
@tornado.web.asynchronous
@gen.coroutine
def get(self):
if self.get_argument('code', None):
user = yield self.get_authenticated_user(
redirect_uri=self.request.full_url(),
client_id=self.settings['weibo_api_key'],
client_secret=self.settings['weibo_api_secret'],
code=self.get_argument('code')) snsId = user['id']
email = '%s@weibo.com' % snsId
nickname = user['screen_name']
profileImg= 'http://tp1.sinaimg.cn/%s/180/0/1' % snsId
session_expires = int(time.time()) + int(user['session_expires'])
result,tp,userId = self.SNSUser(self.SNSType['weibo'],email,nickname,snsId,user['access_token'],json.dumps(user),session_expires,profileImg)
if result:
expiresDays = int(user['session_expires'])/(3600*24)
expiresDays = expiresDays < 1 and 1 or expiresDays
self.userLogin(userId,expiresDays)
url_next=self.get_argument("next", "/")
self.redirect(url_next)
else:
self.redirect('/login')
else:
self.authorize_redirect(
redirect_uri=self.request.full_url(),
client_id=self.settings['weibo_api_key']
)

升级Tornado到4后weibo oauth登录不了的更多相关文章

  1. Yii2 使用 QQ 和 Weibo 第三方登录源码

    我们社区在 yii2-authclient 多次升级后,登录异常.一直想寻求一种通用的方法,尽量不重写 OAuth2, BaseOAuth 以及 OAuthToken 类, 所以本次直接在 initU ...

  2. 解决Spring Boot 从1.x升级到 2.x 后 单点登陆(SSO)问题

    解决Spring Boot 从1.x升级到 2.x 后 单点登陆(SSO)问题   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring S ...

  3. SharePoint 2010升级到sharePoint 2013后,人员失去对网站的权限的原因及解决方法。The reason and solution for permission lost after the upgrading

    昨天碰到了一个问题,一个网站在从SharePoint 2010升级到SharePoint 2013后,人员都不能登录了,必须重加赋权,人员才能登录,这样非常麻烦. 原因:是认证方式的问题.在Share ...

  4. DZ升级到X3.2后,UCenter用户管理中心进不了了

    前天将DZ升级到X3.2后,UCenter用户管理中心进不了了,输入的密码也对,验证码也对,就是点登录后没反应,又回来输入前的状态.如果更换密码后,显示密码错误,证明密码是没错的.但就是进不了.大家看 ...

  5. [IOS NSUserDefaults]的使用:登陆后不再显示登录界面。

    之前搜了好多地方都没找到实现“登陆后不再显示登录界面,而默认自动登录”的方法. 待我发现有种存储方式叫NSUserDefaults的时候,立马又感觉新技能get了. 简介: NSUserDefault ...

  6. 升级10.11.6后CocoaPods的坑,之前10.11.4已经安装好的,居然没了Failed to locate Homebrew!

    升级10.11.6后CocoaPods的坑,之前10.11.4已经安装好的,居然没了,用命令 sudo gem install cocoapod 装不上,换 sudo gem install -n/u ...

  7. 升级xcode6和ios8后,unity遇到的一些小问题

    升级最新的Xocde6后,如果不是最新版本的unity,虽然也可以也可以正常的build,但如果想通过unity连真机进行profile的话,就会在xocde中报错,这个的主要原因是unity的配置里 ...

  8. xcode7.3 升级 xcode8.0 后权限设置问题(升级xcode 8.0 后构建版本不显示问题)

    xcode7.3 升级 xcode8.0 后权限设置问题(升级xcode 8.0 后构建版本不显示问题) 前两天为了适配 iOS10 的系统 我将xcode 7.3 升级到了 xcode 8.0 但是 ...

  9. Remote Desktop manager 连接后无法自动登录

    现象: Remote Desktop manager 连接后无法自动登录 用Windows 自带的远程桌面 可以自动登录 解决方法: 在指定站点 右键 Edit Entry. 如下图处打勾就可以了.

随机推荐

  1. linux下定时器介绍2--timer_create等函数集的使用示例

    程序1:采用新线程派驻的通知方式 程序2:通知方式为信号的处理方式 #include <stdio.h>#include <time.h>#include <stdlib ...

  2. Python Challenge 第 4 关攻略:linkedlist

    代码 import requests url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing={}" ...

  3. Deploy Openstack all-in-one Shell Script

    Deploy Openstack all-in-one Shell Script At present(2015/10), the RDO deploment method can only inst ...

  4. 二十二、springboot之监控管理Actuator

    1.新增spring-boot-starter-actuator的依赖 gradle: compile('org.springframework.boot:spring-boot-actuator') ...

  5. Python基础:获取平台相关信息

    Windows 10家庭中文版,Python 3.6.4, 本文介绍了使用os.platform.sys三个模块获取Python程序的运行平台相关的信息. os模块:提供 各种各样的操作系统接口 os ...

  6. 170406回顾-SQL Server的smalldatetime类型比较

    在比较SQL Server的类型为smalldatetime字段时出现下面的错误:将 expression 转换为数据类型 smalldatetime 时出现算术溢出错误 正确的比较方法如下:将lon ...

  7. 云计算IaaS浅谈

    (本篇文章仅仅是整理文档资料时,发现的一篇课程报告,感觉还挺有参考意义的) 最近几年云计算一直是IT业的热点,一股炽热的云计算浪潮席卷了世界,全世界都在讲云计算,都在搞云计算.虽然最初是由谷歌公司提出 ...

  8. new Function和eval区别

    eval和new Function都可以动态解析和执行字符串.但是它们对解析内容的运行环境判定不同. eval中的代码执行时的作用域为当前作用域.它可以访问到函数中的局部变量. new Functio ...

  9. CVE-2013-1347Microsoft Internet Explorer 8 远程执行代码漏洞

    [CNNVD]Microsoft Internet Explorer 8 远程执行代码漏洞(CNNVD-201305-092) Microsoft Internet Explorer是美国微软(Mic ...

  10. Asp.net mvc 实时生成缩率图到硬盘

    之前对于缩率图的处理是在图片上传到服务器之后,同步生成两张不同尺寸的缩率供前端调用,刚开始还能满足需求,慢慢的随着前端展示的多样化,缩率图已不能前端展示的需求,所以考虑做一个实时生成图片缩率图服务. ...