把 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. Tslib的移植【转】

    转自:http://www.cnblogs.com/uvsjoh/archive/2011/08/25/2152947.html移植Tslib 1 下载源码tslib-x.x.tar.gz 2 解压, ...

  2. mvc 分部视图(Partial)显示登陆前后变化以及Shared文件夹在解决方案资源管理器中没有显示的问题

    刚开始我的解决方案资源管理器中没有显示Shared文件夹,但Shared文件夹在项目中是实际存在的,我搜了下好像没有类似的解答(可能是我搜索的关键词不够准确).后来自己看了下vs2012. 其实解决方 ...

  3. 【写在NOIP前】

    快NOIP了,感觉自己得总结一下吧. 1.要自信啊,相信自己啊,我明明还是有些实力的是吧. 哪怕之前被教练怎么怼,自己别放弃啊 一定要注意心态吧,考试的时候怎么都不能慌,你不会的题也不会有多少人会做的 ...

  4. Runtime - Associated Objects (关联对象) 的实现原理

    主要围绕3个方面说明runtime-Associated Objects (关联对象) 1. 使用场景 2.如何使用 3.底层实现 3.1  实现原理 3.2 关联对象被存储在什么地方,是不是存放在被 ...

  5. Access中替代case when的方法 .

    最近在做一个用Access的东东,其中用到了case when的方式,但是Access是不支持这种语法的,查询知道IIf和Swith可以作为替代,总结如下: IIf(expr, truepart, f ...

  6. spring 学习之二 AOP编程

    AOP概念 AOP, aspect oriented programing,翻译过来就是面向切面编程的意思,那什么叫面向切面编程呢?相对于之前传统的纵向继承方式来对原有功能进行功能扩展, 面向切面编程 ...

  7. OpenJDK,Oracle's OpenJDK,Oracle JDK的区别与选择

    OpenJDK 单纯的OpenJDK指的是JDK的源码,以GPL协议开源,由企业和社区开发者共同维护和开发. Oracle's OpenJDK Oracle started providing ope ...

  8. POJ 1236 Network of Schools(tarjan求强连通分量+思维)

    题目链接:http://poj.org/problem?id=1236 题目大意: 给你一个网络(有向图),有两个任务: ①求出至少同时需要几份副本可以使得整个网络都获得副本 ②至少添加多少信息表(有 ...

  9. Python模块Pygame安装

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查 ...

  10. lr参数化取值与连接数据库

    TXT文本,EXCEL表格以及数据库中的表都可以作为参数的数据集载体,LR都是支持的. 特别提醒: 1.在形成数据池之后,数据库中的数据变化不会影响数据池中的数据. 2.数据文件一定要以一个空行结束, ...