新浪OAuth网站登陆连接,请求access
本文的环境仅仅是针对最新的新浪oauth2.0, 早期的1.0方式我不太了解,也不在本文的范畴内。 解决方案给出两种: 1 ,描述解决思路,各位自己去实现。 2 ,给出我开发好的asp.net 4.0 dll,直接傻瓜化加载使用。 当时,我把电脑屏幕翻转了180度,想看看新浪
本文的环境仅仅是针对最新的新浪oauth2.0, 早期的1.0方式我不太了解,也不在本文的范畴内。
解决方案给出两种: 1,描述解决思路,各位自己去实现。 2,给出我开发好的asp.net 4.0 dll,直接傻瓜化加载使用。
当时,我把电脑屏幕翻转了180度,想看看新浪的文档里面是不是有些什么隐藏说明(因为有先例:九阳真经就是这么来的),要不然为什么我已经正确提交了各个POST参数,依然得到: '{"error":"invalid_request","error_code":21323,"request":"/2/oauth2/access_token","error_uri":"/2/oauth2/access_token","error_description":"miss client id or secret"}' 这样的错误提示。
一切都已经按照文档的说来做了,参见:http://open.weibo.com/wiki/OAuth2/access_token。 我自视水平不高,虽然是个初学者,但是这样的配置还是能够搞定的,可结果偏偏还是错误。
我也不想再列举自己的各种证据了,需要搭建的环境太麻烦,没那功夫,反正遇到这问题的人多的是,搜一搜别人的例子就知道,都是一样的遭遇。
我始终认为是我的错误,而不是新浪的错误,所以,电脑屏幕翻转了180度,没发现什么特别的隐藏说明,接着又拿一块大镜子来看镜像,还是没发现什么,最后使出了绝招: 把文档的所有文字按照奇数和偶数都排列着读一遍,依旧无解。 终于: 我开始觉得不是我的错了,而是新浪的错。
文档中有这么一句提示:
HTTP请求方式:POST
这句话太简单了,你们想要人家POST什么?让人认为所有的参数都要作为POST发送过去。可事实偏偏不是这样的, OAuth的服务端只要看到本次提交的行为是POST就行, 至于POST集合里面有没有数据,有些什么数据,它才不会管,所以,无论我们在POST里面添加了什么键|值、无论怎么切换顺序,都是错误的,因为它就没有去读取。
解决办法只有本着死马当活马医的态度: 乱搞!
最终还是让我发现了----需要使用GET和POST的混合方式来提交:
提交的地址应该是:
"https://api.weibo.com/oauth2/access_token?client_id={0}&client_secret={1}&grant_type=authorization_code&code={2}&redirect_uri={3}"
请求方式:POST
POST中的数据:空!
0,1,2,3 对应你自己的参数值
就是这样,终于正确获得token值,服务器只管你的method是POST就行了,你的实际参数都是在GET里面的。
顺便提一下: 如果采用basic方式在http头中添加key和secret, 最后依然是大同小异的错误,只不过是提示变成了找不到你的redirect_uri参数。
好了,解决思路说完了。如果你不愿自己动手,并且你也和我一样是ASP.NET 4.0开发的话,可以接着往下看:
下载地址:http://files.cnblogs.com/kvspas/SinaOAuth_20111230_v1.zip
组件中已经封装好了直接获取用户基本信息的功能,并且已经强类型化。
组件的一部分功能使用了JSON.NET库(http://json.codeplex.com/)
使用办法:
首先,必须保证运行环境是4.0,因为解析JSON的方式涉及到dynamic类型
1: 页面1
using SinaOAuth;
//第一步,将用户引导到新浪微博登陆地址
var login = new SinaOAuthLogin("你的key", "你的回调地址");
Response.Redirect(login.SinaOAuthLoginUri);
2:页面2
using SinaOAuth;
//第二步,这个页面来自新浪跳转过来,也就是上一步中你设置的回调地址
//本页面的url格式应该是这样的:
//http://www.abc.com/sinaoauth.aspx?code=427bbf62b4b91339951b436c4880e9ef
var code = Request.QueryString["code"];
SinaOAuthApi s = new SinaOAuthApi("你的key", "你的secret", "你的回调地址");
var tokenValue = s.RequestTokenData(code); //包含了uid、expires_in、access_token,请求其它API时候使用
var user = s.RequestUserInfo; //获取用户基本信息
Response.Write(user.name);
好了,就这么简单。 最核心的身份验证部分已经帮你通过了,其它的API就由你*发挥了。
使用其它语言的朋友请参照解决思路自行编码。
这是新浪API团队设计思维上的一个BUG,之所以说是“设计思维”上,是因为没有对生产环境的运行带来坏处,但是这样的文档说明存在二义性、POST不是POST,GET不是GET的机制,难以专业化, 这个系统还有很大的改善空间。