请注意:本页内容发布于 4734 天前,内容可能已经过时,请注意甄别。
饭否的oAuth认证文档在这里:https://github.com/FanfouAPI/FanFouAPIDoc/wiki/Oauth
如果采用他人已经写好的库,则基本不存在什么问题,而如果认证过程是自己写,并且之前又没有多少网络应用的编程经验,只看这个文档可能会走不少弯路。
1.xAuth的基本认证流程
xAuth是oAuth的简化版本,主要用于客户端一类本地应用程序的验证,oAuth的原生认证过程可以参考RFC 5849号文档(英文)及新浪开放平台的oAuth介绍(中文),这里不再赘述,主要介绍饭否提供的xAuth接口的认证流程:
- 使用access_token接口,辅以x_auth系列参数提交客户端认证,换取可用的oauth_token和oauth_token_secret。
- 使用获得的oauth_token和oauth_token_secret,结合申请的应用oauth_consumer_key和oauth_consumer_secret对API进行认证调用。
2.oAuth基本知识
- Header中的参数
关于排列:首先对参数进行字母顺序升序排序,参数名相同的,按参数值排序,然后将排序后的参数按顺序用西文逗号(,)连接起来,作为Header中Authorization段放在“OAuth ”(注意有一个空格)段后的内容。对于饭否的oAuth,须注意:xAuth调用时对realm以及参数值是否有引号不敏感,但通过oAuth进行身份验证调用其它API时,要注意一不能有realm参数,二是参数值不能有引号,如果疏忽了这些问题,服务器会返回Invalid Signature的hash-error结构体,按返回的内容调试即可。 - 签名
签名是为了保证数据未经篡改。不同的站点可能支持不同的签名方式,饭否只支持HMAC-SHA1方式的签名。饭否的xAuth阶段签名不需要使用Key(理论上这样是不对的,以后可能会修改),而在通过oAuth认证调用API功能时,则需要使用Key,Key应为consumer_secret和oauth_token_secret的连接结果,用“&”连接,然后附加到Header中OAuth Authorization的参数中。 - Base String
Base String是计算签名的基础,oAuth规范要求的Base String组合方式在下文有介绍。
3.oAuth过程中需要注意的问题
- 关于oAuth API的使用
如果按照oAuth文档中的指示,仅对那些参数附在Header中进行提交,很可能永远也无法通过认证,为何?RFC5849中已有明确提示(第3.5.1条):必须制定Authorization的Scheme为OAuth(大小写不能错),那什么是Authorization Scheme?其实就是告诉服务器认证的类型,也就是说,提交的Header中,Authorization段必须符合以下格式:Authorization: OAuth //后面是oAuth的其它参数
如果这一步忘记了,服务器只会一个劲的返回Invalid Consumer Key,容易使人在Consumer Key的代入值上百思不得其解,其实只是因为服务器不知道这是oAuth认证,从而根本没有去读后面的参数,等于未将Consumer Key传给服务器,自然就会报Invalid Consumer Key了。
- 关于Base String的生成
Base String的基本格式如下,其中&不是为了好看,而是必须存在的连接符号:
HTTP请求方法(GET或POST,必须为大写)&URL Encode后的目标URL&排序并用西文AND符号(&)连接,然后整体做URLEncode后的参数
这里许多通不过验证的人主要的问题可能是URL Encode后的结果与服务器期望值不符,原因也很简单:可能是所用的编程语言生成的URL Encode结果不标准。RFC中规定的编码需要满足以下两个关键条件:1、所有编码文字(%xx)中,xx的字母必须为大写(例如:%AA可以通过,而%aa就不行) 2、以下字符绝对不能被编码:数字、字母(大写和小写)、-(短横线,或称西文减号)、.(西文小数点)、_(西文下划线)、~(西文波浪号),而除此之外的所有字符必须参加编码。
鉴于此,如果所用的语言生成的结果不符合以上两条,请自行编写函数进行编码工作。
- 关于签名(oauth_signature)
以下是饭否在API文档中提供的签名规则,请完全照做:
1、所有OAuth请求中,所有oauth_(含xauth_)开头的参数都要参加签名。
2、在GET请求中,QueryString的所有参数也要参与签名,如:GET http://api.fanfou.com/statuses/user_timeline.xml?id=fanfou&page=2&format=html
则id=fanfou、page=2、format=html也要参加签名。
3、在POST请求中,只有当Content-Type为application/x-www-form-urlencoded时,
所有参数才都全部要参加签名,如(POST数据没有经过编码):POST http://api.fanfou.com/account/update_profile.xml(更新用户信息) 数据:url=http://www.aoisnow.net&location=山东 济南&description=测试上传用户信息&name=霞羽&[email protected]
则数据中的url、location、description、name、email都要参加签名,且Content-Type需指定。
4、在POST请求中,除了application/x-www-form-urlencoded的Content-Type,其它POST请求的附加
参数都不参与签名,包括Content-Type为multipart/form-data时也不需要。例如(数据没有编码):POST http://api.fanfou.com/photos/upload.xml 数据:photo=(照片的二进制数据)&status=测试&source=test
则数据中的photo、status、source都不参加签名。
5、对于POST请求,经实践证明Content-Type默认为application/x-www-form-urlencoded。
在HTTP协议规定中这是默认值,但在提交给饭否的POST请求中,Content-Type必须指定为此。
否则会出现提交参数正确的情况下返回响应代码为200的空响应,切记。
很详细,学习了。
关于Base String的生成
Base String的基本格式如下,其中&不是为了好看,而是必须存在的连接符号:
HTTP请求方法(GET或POST,必须为大写)&URL Encode后的目标URL&排序并用西文逗号(,)连接,然后整体做URLEncode后的参数
这里逗号是不是改为&了?
确实是,已修改。
博主,看到你的回复真好。不知道有无时间再看看这个
所以求教,本人刚开始学,在获取未授权的Request Token就卡住了。
http://fanfou.com 请求用户名和密码。信息为: “password error”
点取消后出现如下提示
XML解析错误:未组织好
位置:http://fanfou.com/oauth/request_token?oauth_consumer_key=3159c9aa1a54b8734d3da88ee60a60ef&oauth_nonce=2659776296&oauth_signature=cDjegef64pHFH9d+7zJsjM2d674=&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1329888148
行:3,列:94:
我的疑问,
oauth_nonce=2659776296,是不是位数不够?要32位?
这一步HMAC-SHA1加密时的secret后面要不要加&(还没拿到oauth_token_secret)
这个是我的写法。。
https://dl.dropbox.com/u/48168238/3.html
用您提供的链接时而可以成功获取Token,时而不行。
Nonce在RFC中对长度没有限制,但必须在请求过程中唯一(The nonce value MUST be unique across all requests with the same timestamp, client credentials, and token combinations),所以应该不是这个的问题。
出错的时候服务器的返回是/hash/error结构,其中有对Expected BaseString的说明,您可以参考返回对提交进行修正。
非常感谢。
@jaxer
您好我也遇到了相同的问题 请问怎么解决的
万分感谢,调试了一个晚上一直Invalid Consumer Key,加上Content-Type之后终于可以了,再次谢谢^_^