自从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. 如何用WebIDE打开并运行CRM Fiori应用

    访问Web IDE url 在Web IDE里进行项目clone操作: https://:8080/#/admin/projects/fnf/customer/cus.crm.opportunity ...

  2. 快速排序算法思路分析和C++源代码(递归和非递归)

    快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试喜欢考这个. 快速排序是C.R.A.Hoar ...

  3. 【转】转自微信公众号 JavaScript 复杂判断的更优雅写法

    与微信公众号看到一篇js复杂判断的文章,对我启发很大,故转到博客园以供后期不断学习并应用于项目.原文地址:https://mp.weixin.qq.com/s/ClFDRj4MnAxv1dJ5VWKS ...

  4. 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 Apache 服务

    想让我们的阿里云服务器成为一台 Web 服务器,我们需要安装一个 Web 服务器软件,比如 Apache ,或者 Nginx 等等.下面我们就一起来安装一个 Apache 服务. 我们可以使用 yum ...

  5. React后台管理系统-商品列表搜索框listSearch组件

    1.商品列表搜索框 2.搜索框页面的结构为 <div className="row search-wrap">               <div classN ...

  6. GMap.Net解决方案之在WinForm和WPF中使用GMap.Net地图插件的开发

    在做地理位置相关的开发时,总是面临高额地图引擎费用让大部分用户望而却步,加之地图数据又是天价,那么GMap.NET就是首选了,它本身就是开源免费,服务器可以在本地缓存,以后访问时就可以直接访问. 可以 ...

  7. PHP使用CURL_MULTI实现多线程采集

    $connomains = array( "http://www.baidu.com/", "http://www.hao123.com/", "ht ...

  8. 百度之星初赛A 今夕何夕

    今夕何夕 今天是2017年8月6日,农历闰六月十五. 小度独自凭栏,望着一轮圆月,发出了"今夕何夕,见此良人"的寂寞感慨. 为了排遣郁结,它决定思考一个数学问题:接下来最近的哪一年 ...

  9. 笔记-python-standard library-9.6 random

    笔记-python-standard library-9.6 random 1.      random source code:Lib/random.py 1.1.    functions for ...

  10. pyautogui 模块学习

    在日常实施中,我们用控件对大部分的网页和客户端都能进行拾取操作.但是仍有一小部分的应用无法进行操作.这里我常用到 pyautogui 这个模块.下面做个分享. Python 的 pyautogui 模 ...