假设我有一个敏感的JS对象,通过它我可以做关键的事情。我的要求是我想完全包装这个对象,以便没有人可以访问它。这是包装此对象的模式。
var proxy = (function (window){
// A private reference to my critical object (i.e. big apple)
var bigApple = window.bigApple;
// Delete this property so that no one else can access it
delete window.bigApple;
// Oooah, It's mine! I'm now eating it :)
// Public APIs exposed globally
return {
doStuffWithBigApple: function (){
// The Script element being executed now
var who = document.currentScript;
// Access control
if(isLegitimate(who)){
return bigApple.doStuff();
}
}
};
}) (window);
通过此代码,我导出一个名为proxy
的公共文字对象,以便每个人都可以访问它。
那是什么isLegitimate
?它是一个抽象函数,可以决定哪些script
元素可以访问我的大苹果的哪些方法。决定是针对src
元素的script
属性做出的。 (即他们的域名)
其他人使用这样的公共API:
proxy.doStuffWithBigApple();
在我的网络应用程序中,有广告占位符,可以加载和执行包含JavaScript代码的外部内容。所有这些外部资源都渴望访问我的大苹果。
注意:在我的脚本之后添加了这些内容,导致无法访问原始window.bigApple
。
我的安全模型是否有任何规避方法?
关键边缘:
src
属性。 ---不可能,因为src
只能设置一次。script
元素---不会出现问题答案 0 :(得分:2)
您创建代理的想法很好,但是,如果您有权访问ES6,为什么不关注Proxy?我认为它能做到你想要的开箱即用。
MDN提供了关于如何在setter等中进行值验证的陷阱的良好示例
编辑:
可能陷阱我想象过:
IE中不支持document.currentScript
。因此,如果您关心它并决定将其填充/使用预先存在的polyfill,请确保它是安全的。或者它可以用于动态修改document.currentScript
返回的外部脚本URL并使代理偏斜。我不知道这是否会在现实生活中发生。
答案 1 :(得分:1)
这种保护JavaScript对象的方法有一个非常重要的问题需要解决,否则这种方式将无法正常工作。
MDN在此API上注明:
重要的是要注意,如果脚本中的代码被称为回调或事件处理程序,则不会引用
<script>
元素;它只会在最初处理元素时引用该元素。
因此,在回调和事件处理程序中调用proxy.doStuffWithBigApple();
可能会导致框架行为不当。