自从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. 怎样在github里面写个人主页

    1 登录你的账号 打开

  2. Python核心编程——多线程threading和队列

    线程与进程类似不过他们是在同一个进程下执行的,并共享相同的上下文.可以将他们认为是在一个主进程或“主线程”中运行的迷你进程. 线程包括开始.执行顺序和结束三部分.它有一个指令指针,用于记录当前运行的上 ...

  3. Java分代的思考

    我们都知道,java的gc是基于java的分代前提,不管是CMS还是G1,都是基于分代思想:老年代和新生代 思考一:为什么可以分代? 1.java中对象的生命周期是不一样的,在gc中对应年龄的概念. ...

  4. scrum敏捷开发☞

    scrum是什么?说白了就是自带一些规则的工具,团队成员按照scrum的规则计划项目,执行项目,完成项目..可以让团队提高工作效率 当前除了scrum还有其他很多类似的像Kanban,XP,RUP(规 ...

  5. 【BZOJ3172】[TJOI2013] 单词(AC自动机的小应用)

    点此看题面 大致题意: 给你\(N\)个单词,请你求出每一个单词在这\(N\)个单词中出现的次数. 相关题目 这道题应该是洛谷上一道板子题的升级版. \(AC\)自动机 这是一道\(AC\)自动机的简 ...

  6. kubernetes-服务发现service(九)

    service •防止Pod失联    •定义一组Pod的访问策略    •支持ClusterIP,NodePort以及LoadBalancer三种类型    •Service的底层实现主要有ipta ...

  7. CUDA入门需要知道的东西

    CUDA刚学习不久,做毕业要用,也没时间研究太多的东西,我的博客里有一些我自己看过的东西,不敢保证都特别有用,但是至少对刚入门的朋友或多或少希望对大家有一点帮助吧,若果你是大牛请指针不对的地方,如果你 ...

  8. 基于CXF开发crm服务

    1 基于CXF开发crm服务 1.1 数据库环境搭建 1.2 web项目环境搭建 第一步:创建动态web项目 第二步:导入CXF相关jar包 第三步:配置web.xml <context-par ...

  9. CXF学习记录

    1 apache CXF入门 1.1 下载 官网:cxf.apache.org 下载CXF的开发包: Apache CXF = Celtix + Xfire 支持多种协议: SOAP1.1,1.2 X ...

  10. python读取txt写入txt

    http://www.cnblogs.com/allenblogs/archive/2010/09/13/1824842.html