Sina API OAuth

2023-11-04 02:18
文章标签 api sina oauth

本文主要是介绍Sina API OAuth,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用新浪微博API:创建SDK

廖雪峰 / 编程 / 2012-12-29 17:34 / Reads: 20

新浪微博无疑是中国最流行的微博社区,和国外流行的tweeter类似,新浪微博也提供了一整套完善的REST API接口。借助新浪微博的开放API,您可以很容易地将自己的网站接入新浪微博,让数以亿计的新浪微博用户直接登录您的网站而不必注册,您还可以借助新浪微博的开放API获取到用户发表的微博、好友关系等社交信息,从而为用户提供更具个性化的服务。

本文将为您演示如何通过新浪微博API接入您的网站,实现发布和获取微博等基本社交功能。在此之前,我们会首先讨论几个基本概念。

新浪微博API简介

新浪微博不仅通过网站让用户能直接阅读和发布微博,它也提供了一整套比较完善的REST API。REST是Representational State Transfer的缩写,本文不打算详细讨论REST的概念,您可以简单理解一个REST服务是通过标准的HTTP请求和响应来完成资源的访问,比如,我们希望获取某个用户发布的最新的微博消息,该REST API的URL地址:

https://api.weibo.com/2/statuses/user_timeline.json

向以上地址发送标准的HTTP GET请求,并在URL参数中填入相应的参数,就可以从该HTTP响应中获得最新的微博消息,加上参数的URL地址:

https://api.weibo.com/2/statuses/user_timeline.json?uid=1642634100&source=939120710

得到的响应如下(省略了部分内容):

{"statuses":[{"created_at":"Thu Nov 15 16:10:14 +0800 2012","id":3512660609653668,"mid":"3512660609653668","idstr":"3512660609653668","text":"【再见,莲花】IBM宣布,将停用Lotus品牌,Lotus品牌由IBM于1995年收购Lotus公司获得,Lotus的经典产品Lotus 1-2-3于1983年推出,该软件堪称电子表格软件的开山鼻祖。在微软的Excel推出之前,Lotus 1-2-3是电子表格软件市场的王者,直到Excel 2010都可兼容Lotus 1-2-3的格式。http://t.cn/zjZ3EF0","source":"<a href=\"http://e.weibo.com\" rel=\"nofollow\">专业版微博</a>","favorited":false,"truncated":false,"in_reply_to_status_id":"","in_reply_to_user_id":"","in_reply_to_screen_name":"","thumbnail_pic":"http://ww3.sinaimg.cn/thumbnail/61e89b74jw1dyvslw65fhj.jpg","bmiddle_pic":"http://ww3.sinaimg.cn/bmiddle/61e89b74jw1dyvslw65fhj.jpg","original_pic":"http://ww3.sinaimg.cn/large/61e89b74jw1dyvslw65fhj.jpg","geo":null,"user":{"id":1642634100,"idstr":"1642634100","screen_name":"新浪科技","name":"新浪科技","province":"11","city":"8","location":"北京 海淀区","description":"欢迎在微信上关注新浪科技公众号:搜索techsina,或扫描链接中的二维码http://e.weibo.com/1642634100/y...","url":"http://tech.sina.com.cn/","profile_image_url":"http://tp1.sinaimg.cn/1642634100/50/5613120647/0","profile_url":"sinatech","domain":"sinatech","weihao":"","gender":"f","followers_count":2373806,"friends_count":844,"statuses_count":33176,"favourites_count":19,"created_at":"Fri Aug 28 21:07:40 +0800 2009","following":true,"allow_all_act_msg":true,"geo_enabled":true,"verified":true,"verified_type":3,"remark":"","allow_all_comment":true,"avatar_large":"http://tp1.sinaimg.cn/1642634100/180/5613120647/0","verified_reason":"新浪科技官方微博","follow_me":false,"online_status":1,"bi_followers_count":591,"lang":"zh-cn","star":0,"mbtype":0,"mbrank":0,"block_word":0},"reposts_count":117,"comments_count":62,"attitudes_count":1,"mlevel":0,"visible":{"type":0,"list_id":0}},...

JSON数据格式

要与REST API交互,就需要定义数据交换格式。早期的REST API通常支持XML格式,但近年来JSON变得越来越流行,相比XML,JSON更简洁,解析速度更快,并且可以直接被JavaScript操作而无需任何第三方扩展。越来越多的REST API都首选支持JSON格式,新浪微博API也不例外。

OAuth认证

通过新浪微博的API接入网站,由于用户无需在您的网站上注册,就可以直接使用他/她在新浪微博的帐号和口令登录您的网站,这就需要确保您的网站在无需知道,也不能知道用户口令的情况下确认用户已经登录成功。由于用户的口令存储在新浪微博,因此,认证用户的过程只能由新浪微博完成,但新浪微博如何与您的网站通信并告知您用户是否登录成功呢?这个过程称之为第三方登录,OAuth是一个标准的第三方登录协议,借助OAuth,您的网站就可以安全地接入来自新浪微博登录成功的用户。

OAuth目前主要有1.0和2.0两个版本,2.0版对1.0版做了大量简化,API也更简单。新浪微博最新的API也是采用的OAuth 2.0,整个登录流程如下:

  1. 用户在您的网站上点击“使用新浪微博登录”,您的网站将用户重定向到新浪微博的OAuth认证页,重定向链接中包含client_id参数作为您的网站ID,redirect_uri参数告诉新浪微博当用户登录成功后,将浏览器重定向到您的网站;
  2. 用户在新浪微博的认证页输入帐号和口令;
  3. 新浪微博认证成功后,将浏览器重定向到您的网站,并附上code参数;
  4. 您的网站通过code参数向新浪微博请求用户的access token;
  5. 您的网站拿到用户的access token后,用户登录完成。

OAuth的access token是提供认证服务的网站(例如新浪微博)生成的令牌,代表一个用户认证信息。在随后的API调用中,传入该access token就代表这个登录用户,这样,通过OAuth协议,您的网站将验证用户的步骤交给新浪微博完成,并由新浪微博告知您用户是否登录成功。

OAuth的安全性是通过步骤4完成的,通过code参数获取access token的过程是您的网站后台到新浪微博网站完成的,用户无法看到获取access token的HTTP请求。如果用户传入伪造的code,则新浪微博会返回一个错误。

准备开发环境

本文的开发环境是Python 2.7。用Python开发Web应用非常简单,Python通过WSGI接口来提供标准的HTTP服务,并且,标准的Python包已自带一个简单的WSGI服务器,可以用于本地开发与测试。

编写Python SDK

虽然可以直接使用urllib或httplib包调用新浪微博的API,但这会使我们无法抽象出新浪微博API调用的业务接口。因此,我们第一步的目标是把新浪微博的REST API通过SDK封装,并将其转换为Python的函数调用。

新浪微博提供了非常丰富的基于JSON的API,并且还在不断添加和更新中。编写SDK的挑战在于,SDK的接口要简单易用,这样客户端调用起来才能很方便,如果新浪微博API有了更新,SDK能不必更新就能支持新的API,那就大大降低了SDK的维护成本。此外,不同语言的SDK要结合语言本身的特点和约定俗成的编程模式。我们的SDK实现需要充分利用Python语言的动态特性,一切API调用都是动态调用,API参数采用关键字参数传入,这样,SDK本身不必修改,就可以支持新的API。

下面,我们来一步一步实现SDK。

申请App

要通过新浪微博连接您的网站,首先需要在新浪微博注册一个App,作为您的网站的ID标识。新浪微博会分配一个App ID和一个App Secret,App Secret是您的网站和新浪微博共享的密钥,用于API通信时让新浪微博验证API请求确实是从您的网站发出的而不是他人假冒的。

请注意,在您的网站未通过审核前,您需要手动添加测试微博帐号,只有测试用户才能在审核前正常访问API。

准备工作:

您需要准备好您的App ID,App Secret,以及您的网站回调地址。以下代码是网站sinaweibopy.sinaapp.com的定义常量。代码如下:

# 请根据自己的应用修改常量:
_APP_ID = '123456'
_APP_SECRET = 'abc123xyz456'
_REDIRECT_URI = 'http://sinaweibopy.sinaapp.com/auth/callback'

需要根据您的设置修改常量值。

我们定义一个APIClient类,保存app id,app secret和redirect uri,代码如下:

class APIClient(object):def __init__(self, app_key, app_secret, redirect_uri):self.client_id = app_keyself.client_secret = app_secretself.redirect_uri = redirect_uri

有了class,我们需要添加的第一个方法是获取新浪微博认证的URL,可以参考新浪微博的相关API文档,代码如下:

class APIClient(object):...def get_authorize_url(self):return 'https://api.weibo.com/oauth2/authorize?response_type=code&client_id=%s&redirect_uri=%s' % (self.client_id, _encode(self.redirect_uri))

get_authorize_url()方法返回新浪微博的认证页面,我们可以将其打印出来,地址类似:

https://api.weibo.com/oauth2/authorize?redirect_uri=http%3A//sinaweibopy.sinaapp.com/auth/callback&response_type=code&client_id=2373761036

粘贴到浏览器的地址栏中,就可以看到新浪微博的认证页,如图所示:

weibo-signin-page

当用户成功认证后,新浪微博将跳转至我们传入的redirect_uri,并附上code参数,可以在浏览器地址栏中看到该地址,如图所示:

weibo-signin-redirect

如果域名不存在,或者Web服务器没有运行,浏览器会显示404错误,可以在本地hosts文件中把域名映射到本机,然后在本地80端口启动Web服务器。不过,目前没有Web服务器并不妨碍我们继续编写SDK。我们从浏览器地址栏粘贴出code参数后,就可以用它来交换access token,方法request_access_token()就用于请求一个access token,代码如下:

class APIClient(object):...def request_access_token(self, code):resp = _post('https://api.weibo.com/oauth2/access_token', \client_id = self.client_id, \client_secret = self.client_secret, \redirect_uri = self.redirect_uri, \code = code, \grant_type = 'authorization_code')logging.info(resp)current = int(time.time())r = json.loads(resp)return JsonDict(access_token=r.access_token, expires=r.expires_in + current, uid=r.uid)

其中,_post函数将发送一个HTTP POST请求,传入参数client_id、client_secret、redirect_uri、code和grant_type,新浪微博返回一个JSON格式的字符串,将它打印出来类似:

{"access_token": "123ABC456XYZ","expires_in": 3600,"uid": "12345678"
}

我们将过期时间expires_in转化为绝对时间后,以JsonDict返回,并包含用户的ID。

JsonDict是一个继承自dict的类,不但可用d['key']访问,也可直接用d.key访问,代码如下:

class JsonDict(dict):def __getattr__(self, attr):return self[attr]def __setattr__(self, attr, value):self[attr] = value

可以使用代码在命令行获得access token:

client = APIClient(_APP_ID, _APP_SECRET, _REDIRECT_URI)
# 从浏览器地址栏粘贴code参数:
code = raw_input('Input code: ')
print (client.request_access_token(code))

一旦获得了access token,就可以开始调用API了。我们通过set_access_token函数来为APIClient保存access token,代码如下:

class APIClient(object):...def set_access_token(access_token, expires):self.access_token = str(access_token)self.expires = float(expires)

新浪微博提供了100多个API接口,如果我们为每个API都编写一个函数来处理不同的API请求,不但工作量巨大,而且我们需要不断维护新浪微博新增的和修改的API接口,费时费力,还容易出错。

考虑到Python是一个动态语言,与传统的静态语言Java、C++等不同,我们可以充分利用动态语言的特性,在不必为每个API都编写函数的情况下,允许客户端按照以下规则调用API。

首先,通过新浪微博文档可以查询到每个API的URL和参数,例如,获取当前登录用户及其所关注用户的最新微博:

URL:statuses/home_timeline
HTTP请求格式:GET
请求参数:
source:采用OAuth授权不需要此参数;
access_token:OAuth授权的参数;
since_id:可选,返回ID比since_id大的微博;
max_id:可选,返回ID小于或等于max_id的微博;
count:可选,单页返回的记录条数;
page:可选,返回结果的页码;
…

其中,access_token对每个API都是必填参数,由APIClient内部处理,然后,将URL的“/”变为“.”,实现链式调用,最后,根据HTTP请求格式调用get()或post(),并传入**kw关键字参数。例如,我们希望能通过如下代码方式调用该API:

r = client.statuses.home_timeline.get(count=50, page=1)
print r
# {"statuses":[{"created_at":"Thu Nov 15 16:10:14 +0800 2012","id":3512660609653668,"idstr":"3512660609653668","text":"…"}]

这样,用户根据新浪微博的API文档,就可以自己构造出API调用。每个API调用返回值自动转化为JSON对象后返回。

下面,我们来实现该调用。

由于Python的动态特性,调用一个class的方法或字段实际上都是查找相应的属性,当该属性不存在时,Python会调用特殊方法__getattr__()试图获得该属性,因此,我们重写__getattr__()并返回一个_Callable对象即可。代码如下:

class APIClient(object):...def __getattr__(self, attr):return _Callable(self.access_token, attr)

_Callable对象也重写了__getattr__()以支持动态调用,并在调用get()或post()方法时返回_Executable对象,代码如下:

class _Callable(object):def __init__(self, access_token, path):self.access_token = access_tokenself.path = pathdef __getattr__(self, attr):if attr=='get' or attr=='post':return _Executable(self.access_token, attr.upper(), self.path)return _Callable(self.access_token, '%s/%s' % (self.path, attr))

_Executable对象虽然是class,但重写了__call__()方法,因此是一个可调用对象,可以直接实现函数调用。代码如下:

class _Executable(object):def __init__(self, access_token, method, path):self.access_token = access_tokenself.method = methodself.path = pathdef __call__(self, **kw):url = 'https://api.weibo.com/2/%s.json' % self.pathreturn _http_call(url, self.method, self.access_token, **kw)

这样,用户通过API文档,就可以自行构造出任意API调用的函数链,不但极大地简化了SDK的编写,而且调用接口简单明了。

通过access token发送微博的代码如下:

client = APIClient(_APP_ID, _APP_SECRET, _REDIRECT_URI)
client.set_access_token(access_token, expires)
client.statuses.update.post(status=u'通过Python SDK发微博')

本文的SDK源码可以从GitHub下载:

https://github.com/michaelliao/sinaweibopy/blob/master/weibo.py

参考资料

新浪微博开发文档:http://open.weibo.com/wiki/


这篇关于Sina API OAuth的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/342523

相关文章

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

如何更优雅地对接第三方API

如何更优雅地对接第三方API 本文所有示例完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/third 我们在日常开发过程中,有不少场景会对接第三方的API,例如第三方账号登录,第三方服务等等。第三方服务会提供API或者SDK,我依稀记得早些年Maven还没那么广泛使用,通常要对接第三方

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

小技巧绕过Sina Visitor System(新浪访客系统)

0x00 前言 一直以来,爬虫与反爬虫技术都时刻进行着博弈,而新浪微博作为一个数据大户更是在反爬虫上不遗余力。常规手段如验证码、封IP等等相信很多人都见识过…… 当然确实有需要的话可以通过新浪开放平台提供的API进行数据采集,但是普通开发者的权限比较低,限制也比较多。所以如果只是做一些简单的功能还是爬虫比较方便~ 应该是今年的早些时候,新浪引入了一个Sina Visitor Syst

Restful API 原理以及实现

先说说API 再说啥是RESRFUL API之前,咱先说说啥是API吧。API大家应该都知道吧,简称接口嘛。随着现在移动互联网的火爆,手机软件,也就是APP几乎快爆棚了。几乎任何一个网站或者应用都会出一款iOS或者Android APP,相比网页版的体验,APP确实各方面性能要好很多。 那么现在问题来了。比如QQ空间网站,如果我想获取一个用户发的说说列表。 QQ空间网站里面需要这个功能。

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a

WordPress开发中常用的工具或api文档

http://php.net/ http://httpd.apache.org/ https://wordpress.org/ https://cn.wordpress.org/ https://core.svn.wordpress.org/ zh-cn:开发者文档: https://codex.wordpress.org/zh-cn:%E5%BC%80%E5%8F%91%E8%80%

Java后端微服务架构下的API限流策略:Guava RateLimiter

Java后端微服务架构下的API限流策略:Guava RateLimiter 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在微服务架构中,API限流是保护服务不受过度使用和拒绝服务攻击的重要手段。Guava RateLimiter是Google开源的Java库中的一个组件,提供了简单易用的限流功能。 API限流概述 API限流通过控制请求的速率来防止

Docker远程连接和Docker Remote Api

在Docker生态系统中一共有3种API:Registry API、Docker Hub API、Docker Remote API 这三种API都是RESTful风格的。这里Remote API是通过程序与Docker进行集成和交互的核心内容。 Docker Remote API是由Docker守护进程提供的。默认情况下,Docker守护进程会绑定到一个所在宿主机的套接字:unix:///v

基于MinerU的PDF解析API

基于MinerU的PDF解析API - MinerU的GPU镜像构建- 基于FastAPI的PDF解析接口 支持一键启动,已经打包到镜像中,自带模型权重,支持GPU推理加速,GPU速度相比CPU每页解析要快几十倍不等 主要功能 删除页眉、页脚、脚注、页码等元素,保持语义连贯对多栏输出符合人类阅读顺序的文本保留原文档的结构,包括标题、段落、列表等提取图像、图片标题、表格、表格标题自动识别