巧解傲游插件OAUTH的跳转问题
在前面的新浪微博开放平台历险一文中,提到了开发浏览器微博插件时,如果要进行OAUTH认证时,为了避免跳转到本地页面,实现方式是通过新浪微博的callback=json方式,前台让用户输入用户名和密码,后台请求微博API获取verifier。
在开发腾讯微博插件时,我发现其实还有另外一个非常巧妙的方式可以解决此问题。
让我们回到开始,我们的本地页面地址是“file:///C:/Program%20Files/Maxthon2/Plugin/QQT/index.html”,将此地址作为callback参数传递给request token api,并点击authorize api api和token构成的链接进入微博授权页面:
输入用户名密码后,按照OAUTH协议的流程,页面应该从腾讯微博的授权页面跳转到本地页面。看一看,页面已经变成本地页面了,那么这样看来本地页面的OAUTH授权流程应该没有问题。但是仔细一看,发现地址栏的URL没有改变,仍然是之前的url!
而我们alert一下location.href看一下:
按照正常的location redirect,外部跳转地址栏是应该进行改变的,但是这次腾讯微博的认证时,从腾讯微博的页面跳转到本地页面,页面改变了,地址栏却没有改变,这样会带来什么问题呢?
傲游插件机制里,安全部分是通过地址栏的url来识别和控制的,如果url识别不是本地页面,就会对本地操作进行限制,例如读写本地配置文件的external.m2_readIni和external.m2_writeIni方法,还有跨域的Ajax操作。
所以url仍然保持在t.qq.com域下时,无法读写配置文件里的oauth_token,无法像正常插件一样进行跨域Ajax操作去获取微博数据。这里可以想到的解决方案是location.href可以获取oauth_token和oauth_verifier,那么再进行一次跳转,跳转到本地页面,同时将oauth_verifier和oauth_token传递到本地页面,另外附加一个标识或者识别不同的域名防止进行重复跳转。页面加载时的初始判断逻辑如下所示:
现在还剩下一个问题,在t.qq.com域名下,我们如何来知道本地插件页面的地址?在正常插件里,可以通过external.m2_plugin_folder( max_security_id , plugin_name)来取得,但是在t.qq.com域下却无法使用;在程序里面写死是不可取的,因为用户安装傲游的路径可能不一样,所以“file:///C:/Program%20Files/Maxthon2/Plugin/QQT/index.html”和“file:///D:/Program%20Files/Maxthon2.5/Plugin/QQT/index.html”都是可能的;我们也不可能让用户来修改或者设置插件路径,那样不是一个好的用户体验。
在没有其他办法的情况下,考虑一下,是否能在本地页面跳转到授权页面前设置好plugin的路径,在跳转的时候来进行读取?因为页面要重新加载,所以此路径必须写在文件里,再简化一下,插件可以写本地的ini文件,我们有没有办法让js文件可以读取ini文件,那么我们就可以从ini文件里取得js的变量了。
傲游插件体系里的写本地配置文件的语法如下:
external.m2_writeIni(max_security_id, plugin_name, config_file, section_name, name, value)
先看看一个典型的傲游插件的ini文件:
[test@gmail.com]
oauth_token=338d44c90d9e47e6a0e7211e75820ecf
其中的test@gmail.com就是section_name,oauth_token就是name,338d44c90d9e47e6a0e7211e75820ecf就是value。
先将section_name设置为空字符串,将name设置为’var plugin_path’,将value设置为通过external.m2_plugin_folder获取的插件本地页面路径试一试。
得到的配置文件如下所示:
[]
var plugin_path = ‘file:///C:/Program%20Files/Maxthon2/Plugin/QQT/index.html’
这个文件是js无法读取的,因为开头有个未知的’[]’,考虑一下,如何能让[]失效呢,如果是用注释包裹起来是有可能的。注意到writeIni函数每次都是向ini文件里添加属性,我们先新建一个ini文件,在开头写上’/*’,然后将name的值设置为’*/ var plugin_path’,再次试验,得到的ini文件如下所示:
/*
[]
*/ var plugin_path = ‘file:///C:/Program%20Files/Maxthon2/Plugin/QQT/index.html’
这个已经是一个js可以正常读取的文件了。试验一下,页面正确的读取了本地页面的路径,并成功跳转,实验成功!
下面是成功读取的信息:
总结:开发中经常遇到一些稀奇古怪的问题,我们利用已有的知识,灵活变通,总会找到解决的办法。