自从sina微博oauth2出来以后, 第三方集成开发简单了很多. Oauth2不像oauth1一样需要后台httpclient请求那么麻烦, 一切都可以在前台使用ajax实现了. 很多人觉得蹊跷, 对于一个第三方应用, 如何不走后台,而在前台使用ajax, 来获取access token? 又如何向sina发起get或post请求? 这其中最难解决的问题当属跨域问题. 这篇文章将彻底解决这些疑问.

OAuth

OAuth为一种授权认证机制. 它牵扯到服务提供方(sina weibo), 用户, 第三方应用(比如糗事百科).  第三方应用想方便用户可以在它的应用里面直接访问自己的weibo信息,还可以把第三方的信息发送到weibo, 比如转发糗事到sina weibo. 实现这个功能, 首先需要第三方应用拥有用户和sina的授权. 在拿到授权以后,第三方应用才能实现集成功能. 为什么不直接给第三方用户密码而用授权机制, 这种问题就不罗嗦了.

拿糗百为例,授权的过程为: 1, 糗百打开一个window或iframe, location指向weibo oauth授权界面. 2, weibo授权界面是在sina的域名下,是由sina的服务器控制的. 授权界面要求用户填写sina的账户,并确认授权. 3, 用户确认以后, 请求发回给sina. sina产生一个access token, 并发回给糗百. OAuth1使用httpclient, OAuth2使用跨域方法. 4, 糗百保留用户的access token. 5, 用户在糗百发起分享糗事到sina, 糗百将糗事和access tokent一并发给sina. OAuth1使用httpclient, OAuth2使用跨域方法.

以上就是授权过程. OAuth1使用类似httpclient的方法与sina交流. 这没有什么疑问,我就不多讲了. access token的产生和验证也不是本文要讨论的. 本文要讨论的是, OAuth2中实现的疑惑. 第三方应用是如何通过跨域方法拿到sina的access token的? 它又是如何通过跨域方法向sina发起get或post请求的?

window.postMessage与window.name

在讲sina的框架的之前,先熟悉两个常见的跨域方法. window.postMessage和window.name.

两个window或iframe之间,只要能拿到对方window的句柄,就可以向对方发送消息. 方法为

1 otherWindow.postMessage(message, targetOrigin);

如果对方注册了事件监听就可以收到message.

1 if (window.addEventLister) {
2   window.addEventLister("message", function(message){});
3 } else {
4   window.attachEvent("onmessage", function(message){});
5 }

通过此种方法,可以在两个不同域的window之间相互传递信息.

因低于IE8的IE浏览器是不支持postMessage,所以还可以使用window.name来传值. 如果写的复杂,则可以使用window.name来模拟postMessage的功能. window.name的局限是,只有同域下才能相互访问window.name,所以使用window.name来跨域传值,要花费不少功夫.

window.name跨域最典型的方法是使用代理页面. 比如domain A下有a.html, domain B下有b.html. a.html如何传值给domain B呢? a.html可以先创建一个iframe, 然后赋予新iframe的contentWindow.name一个message. 然后,将iframe的src指向domain B的代理页面b-proxy.html. 这时候,b.html可以访问b-proxy.html的window.name获取message. 监听window.name变化可以使用setInterval来轮询.

sina weibo就是使用的上面方法. 首选postMessage, 如果不支持postMessage, 则使用window.name.  由于其js写的太复杂,压缩以后更加难看.所以我一直没看明白它是如何使用window.name的,但原理跟上面是一样的.

Weibo oauth2 框架

首先看图

1,  第三方应用首先在sina处申请SDK的使用. 从而获得一个JS的引用地址. 2,  第三方将JS的引用放入自己的页面, 看黄色的"Weibo javascript". 3,  (授权过程没有画在图上) 当第三方想得到用户授权的时候, 调用WB2.login()函数. weibo js弹出一个window, window的location指向sina的oauth2资源. 用户在window中输入用户密码,提交到sina, sina返回一个自关闭页面. 自关闭页面在关闭前,会将带回来的access token用window.opener.postMessage()的方法传回给weibo js所注册的message监听方法. 然后weibo js得到access token, 将其存入第三方应用的cookie下. 4,  第三方应用开始通过Weibo js向sina发起资源请求. 5,  Weibo js首先创建一个iframe, iframe中引入了sina client js. 此iframe跟第三方页面同源. 6,  Client js又创建了一个iframe, iframe的src指向sina xd.jsp, 并引入了sina的xd.js. 7,  xd.js跟sina同源, xd.js发起带有access tokent的XMLHttpRequest, 从sina得到资源. 8,  xd.js通过postMessage或者window.name的方式回传给正在监听等待的client iframe. 9,  client iframe js再回传给weibo js. 10, weibo js调用第三方页面的callback函数,并把获得的资源传给它. 11, callback分析资源,显示在页面上.

为什么使用client iframe? 去掉它好像也可以的样子. 我说下对client iframe的猜想, sina不想暴露太多的接口. weibo js就像接口, 尽量短小精悍. 将复杂的逻辑处理放在动态创建的client js里面. 其次,由于某些低版本的浏览器不支持postMessage, 所以需要使用window.name来模拟postMessage功能, 需要使用代理,我怀疑client iframe就起到一个代理功能. 不过他们的代码本身写的就结构庞大,使用了大量的闭包,再用工具对js压缩了一遍,实在是看不清楚他们如何使用window.name的. 万变不离其宗吧.

Sina微博OAuth2框架解密的更多相关文章

  1. OAuth简介及sina微博开放平台

     OAuth简介及sina微博开放平台 2010-10-26 13:15:25 标签:新浪 sina 微博 OAuth 开放平台 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者 ...

  2. [转] - Weiflow——微博机器学习框架

    Weiflow--微博机器学习框架 本文从开发效率(易用性).可扩展性.执行效率三个方面,介绍了微博机器学习框架Weiflow在微博的应用和最佳实践. 在上期<基于Spark的大规模机器学习在微 ...

  3. 微博开源框架Motan初体验

    前两天,我在开源中国的微信公众号看到新浪微博的轻量Rpc框架--Motan开源了.上网查了下,才得知这个Motan来头不小,支撑着新浪微博的千亿调用,曾经在2014年的春晚中有着千亿次的调用,对抗了春 ...

  4. 微博RPC框架motan入门笔记

    Motan 是一套高性能.易于使用的分布式远程服务调用(RPC)框架. 功能 支持通过spring配置方式集成,无需额外编写代码即可为服务提供分布式调用能力. 支持集成consul.zookeeper ...

  5. Dobbo的继任者?试用微博RPC框架Motan

    从14年开始就陆续看到新浪微博RPC框架Motan的介绍,时隔两年后,微博团队终于宣布开源轻量级RPC框架Motan,项目地址: https://github.com/weibocom/motan/ ...

  6. 腾讯微博OAuth2.0认证介绍

    腾讯微博开放平台,是基于腾讯微博系统,为广大开发者和用户提供的开放数据分享与传播平台. 广大开发者和用户登录平台后,就可以使用平台提供的开放API接口,创建应用从微博系统获取信息,或将新的信息传播到整 ...

  7. [PHP] 调用微博API 发微博OAuth2.0

    在实际测试中出现很多问题, 第一就是按照文档调用ACCESS_TOKEN的时候费老劲啦,因为是编辑线上的,有好多中文空格,没有看出来!整了好久! 第二个就是在调用api发微博的时候出现乱码!必须把发送 ...

  8. nodejs express 框架解密1-总体结构

    本文是基于express3.4.6的. 1.express 代码结构为: bin/express 是在命令行下的生成express 框架目录文件用的 lib/express 是框架的入口文件 lib/ ...

  9. python Sina微博自动转发带抽奖字样的微博,添加关注,取消关注

    项目地址:https://github.com/chengshuyi/SinaWeibo 具有的功能 转发带抽奖字样的微博并可以@相应数量的好友 提取关注并添加关注 取消关注 获取粉丝列表

随机推荐

  1. [转]iOS开发总结之代码规范

    转自:http://www.cocoachina.com/ios/20151014/13678.html 命名规范 总 的来说, iOS命名两大原则是:可读性高和防止命名冲突(通过加前缀来保证). O ...

  2. Coursera 算法二 week2 Seam Carving

    这周作业设计到的算法是有向无环图的最短路径算法,只需要按照顶点的拓扑顺序去放松顶点即可.而在这个题目中拓扑顺序就是按照行的顺序或列的顺序. 用到的数据结构为一个二维数组picture同来存储每个像素的 ...

  3. Uploadify 3.2 参数属性、事件、方法函数详解以及配置

    一.属性 属性名称 默认值 说明 auto true 设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传 . buttonClass ” 按钮样式 buttonCursor ‘ ...

  4. Aizu 0525 Osenbei(状压+贪心)

    题意:翻煎饼,只能横着翻或者竖着翻.问最多有多少朝上? 行只有10,所以枚举一下2^10的状态,每列取0或1中最大的一个. 在枚举外面把饼翻好,枚举里面指针指一下就好.(位运算或bitset乱搞 #i ...

  5. 2018.5.28 Oracle数据库补充

    select * from (select rownum rn,e2.* from (select e1.* from emp e1)e2 where rownum<=10)e3 where e ...

  6. 解决Postgresql服务启动又关闭的问题

    查看日志发现如下错误消息:%t LOG: could not receive data from client: An operation was attempted on something tha ...

  7. 1269: [AHOI2006]文本编辑器editor

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5269  Solved: 2037[Submit][Status][Discuss] Descript ...

  8. 【C++学习笔记】 链式前向星

    链式前向星是一种常见的储存图的方式(是前向星存图法的优化版本),支持增边和查询,但不支持删边(如果想要删除指定的边建议用邻接矩阵). 储存方式 首先定义数组 head[ i ] 来储存从节点 i 出发 ...

  9. Jquery 就是怎么取得一个select的当前值

    <select id="cursel">: <option value="1">值1</option>: <optio ...

  10. 微信小程序navigator的open-type跳转问题

    navigator的open-type属性 可选值 'navigate'.'redirect'.'switchTab',对应于wx.navigateTo.wx.redirectTo.wx.switch ...