把 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. MySQL分页存储过程

    CREATE PROCEDURE ProcPage(in tableName varchar(20),#表名  in showField varchar(100),#要显示的列名  in whereT ...

  2. oracle11g的冷热备份

    1.冷备份 如果数据库可以正常关闭,而且允许关闭足够长的时间,那么就可以采用冷备份(脱机备份),可以是归档冷备份,也可以是非归档冷备份.其方法是首先关闭数据库,然后备份所有的物理文件,包括数据文件.控 ...

  3. Python构造方法、析构方法和单例模式

    一.__init__()方法 __init__()通常在初始化一个类实例的时候调用,如: class Student(object): def __init__(self,name,age): sel ...

  4. PHP计算字符串的长度

    <?php /** * 计算字符串的长度(汉字按照两个字符计算) * * @param string $str 字符串 * * @return int */ function str_len($ ...

  5. 回归模型效果评估系列3-R平方

    决定系数(coefficient of determination,R2)是反映模型拟合优度的重要的统计量,为回归平方和与总平方和之比.R2取值在0到1之间,且无单位,其数值大小反映了回归贡献的相对程 ...

  6. class getConstructor newinstance

    public static void main(String[] args) throws Exception{ /**获取String对象指定的构造方法(通过方法的参数类型,传递 参数的 Class ...

  7. MySQL约束笔记

    MySQL 查看约束,添加约束,删除约束 添加列,修改列,删除列 · 查看表的字段信息:desc 表名; · 查看表的所有信息:show create table 表名; 添加主键约束:alter t ...

  8. CentOS7.5搭建ELK6.2.4集群及插件安装

    一 简介 Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎.它允许您快速,近实时地存储,搜索和分析大量数据.它通常用作支持具有复杂搜索功能和需求的应用程序的底层引擎/技术. 下载地址 ...

  9. 【LOJ】#2067. 「SDOI2016」硬币游戏

    题解 c一样的就是一个独立的游戏 我们对于2和3的指数 sg[i][j] 表示\(c \cdot 2^i \cdot 3^j\)的棋子,只有这个硬币是反面,翻转的硬币是正面的sg值 枚举sg函数所有可 ...

  10. 【LOJ】#2340. 「WC2018」州区划分

    题解 学习一个全世界人都会只有我不会的东西 子集变换! 难道我要把这题当板子讲?等等这题好像是板...WC出板题好刺激啊= = 假装我们都做过HAOI2015的FMT题,我们都知道一些FMT怎么解决或 ...