自从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. JavaScript:理解worker事件api

    如果你不是很了解Event事件,建议先看我上一篇随文javascript:理解DOM事件.或者直接看下文worker api. hack 首先,我们需要实例一个Worker的对象,浏览器会根据新创建的 ...

  2. Java代码工具箱之链接Oracle

    1. 需要oracle的 odbc  jar包 2. 代码 3. 注意:ps对象和statement对象最好用完立即释放,尤其是读写数据库代码出现在 for 循环语句中时. 否则会出现游标不够的情况, ...

  3. UsbKey开发

    http://slf-1983.blog.163.com/blog/static/2990236320121113113955119/

  4. ORTP-0.27.0移植

    注意: a. 对于0.27一下版本的ORTP的交叉编译则没有一下依赖库 b. 交叉编译工具链是: arm-linux-gnueabihf-gcc-4.9.1 (4.9版本一下的编译bctoolbox出 ...

  5. SPOJ2713GSS4 - Can you answer these queries IV(线段树)

    题意 Sol 讲过无数次了..很显然,一个$10^12$的数开方不超过$8$次后就会变为$1$ 因此直接暴力更改即可,维护一下这段区间是否被全改为了$1$ 双倍经验:https://www.luogu ...

  6. [BZOJ] 2044: 三维导弹拦截

    排序去掉一维,剩下两维可以直接\(O(n^2)\)做,也可以用二维树状数组(但是不方便建边),解决第一问 第二问,按转移顺序连边,建出DAG,求最小不可重链覆盖即可 #include<algor ...

  7. java中如何设置HTTP协议的头信息(header)

    首先,我们先看一下http的头信息到底是什么:HTTP(HyperTextTransferProtocol) 即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用了请求/响应模型,浏览器或其他 ...

  8. Nginx+proxy_cache图片缓存

    搭建图片缓存机制的原理在于减少数据库的负担并加快静态资源的响应. 步骤: 1. vim /usr/local/nginx/conf/nginx.conf 2. http{     ...     .. ...

  9. 七、MySQL 选择数据库

    MySQL 选择数据库 在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库. 从命令提示窗口中选择MySQL数据库 在 mysql> 提示窗口中可以很简 ...

  10. Iframe父子间元素操作

    1.在父页面 获取iframe子页面的元素 (在同域的情况下 且在http://下测试,且最好在iframe onload加载完毕后 dosomething...) js写法 a.通过contentW ...