我打算将Ext JS用于大型应用程序。该应用程序的功能基于角色。用户登录时,他们只会看到与其相关的菜单和屏幕功能。我的服务器端技术将是Java和JSP。
为了解决这个问题,我有两个想法 。1.使用服务器端技术在用户登录后动态创建与Ext JS相关的javascript。Servlet / JSP将根据用户角色创建必要的est js代码。
2.具有在视图JSP中设置的Js变量,这些变量将用于确保仅正确的功能对用户可用。
什么是确保安全并在Ext Js应用程序中提供基于角色的UI的最佳方法。 在此先感谢您的想法。
阿卜杜勒·奥拉卡拉
我必须在当前开发的应用程序中解决类似的问题,但是权限基于用户所在的国家/地区。
我知道您已经这样做了,但是为了重申阅读者的利益, 应该始终在服务器端实现权限,而JavaScript安全始终是次要的 。这是因为任何半个头脑的人都可以使用小书签或Firebug来执行任意JavaScript,并规避客户端的安全性。
我发现有几种方法可以做到这一点,但是有两种方法最为理智。无论采用哪种方法,都需要考虑两件事:1)服务器使用什么JavaScript,以及如何避免提供不必要的逻辑,以及2)如何避免执行用户不可用的逻辑。
我的应用程序中的所有小部件都是通过延迟加载的dojo.require,因此无需担心不必要地包含了不适用于用户的JavaScript。我对ExtJs库不是很熟悉,但是据我所知,它没有提供可比的方法。但是,必须先进行同步ajax调用,然后进行eval。无论如何,在这种方法中,重要的是组件功能不要跨不同文件(同样,这通常是好的设计)。每个文件应该是自己的类,用于控制特定的小部件或其他UI元素。
dojo.require
然后,我在服务器生成的JavaScript配置类中设置权限。然后可以在整个应用程序中引用该类的内容,以了解什么是允许的以及不允许的是什么。
例如,以下方法控制对全局控件中可用的大多数窗口小部件的访问。
com.project.frontController.prototype.init = function(widgets) { var permissions = com.project.config.permissions; // For each widget in the controller for ( var i=0, l=widgets.length; i<l; ++i ) { // If access is restricted to the widget (by id), then disable it. if ( !permissions[ widgets[i].id ] { com.project.util.disable(widgets[i].btnAccessNode); } // Otherwise, leave it enabled and connect the necessary event handlers. else { // connect an onclick handler or whatever is required for the widget } } };
和配置看起来像:
com.project.config.permissions = { "widgetAbc": { btnAccessNode: "#some-css-selector", otherWidgetConfig: "etc" }, "widgetXyz": { btnAccessNode: "div.some-css-selector" } };
某些应用程序会将其所有JavaScript编译为一个文件,然后将其提供给客户端。如果您的应用程序执行了此操作,并且您可以设法动态执行此操作,则可以在服务器端确定所有必需的JS,然后再为其提供服务。当然,这会产生一些开销。但是,您可以按角色缓存已编译的版本。如果角色很少,那么可以很容易地对该缓存进行初始化,而只需添加一个特定的脚本即可。
由于仅允许使用的JavaScript可用,因此在尝试执行所需的类/函数之前,只需检查其是否可用即可,这是您进行权限检查所需要做的全部工作。
例如,您的脚本包含可能如下所示:
<script type="text/javascript" src="/js/compiler.php?role=moderator"></script>
您的功能检查将如下所示:
com.project.frontController.prototype.init = function(widgets) { // For each widget in the controller for ( var i=0, l=widgets.length; i<l; ++i ) { // If the widget controller doesn't exist, disable it. if ( !com.project.util.widgetExists[ widgets[i].id ] { com.project.util.disable(widgets[i].btnAccessNode); } // Otherwise, leave it enabled and connect the necessary event handlers. else { // connect an onclick handler or whatever is required for the widget } } };
要么
com.project.someWidget.prototype.launchOtherWidget = function() { if ( typeof otherWidget != "undefined" ) { (new otherWidget()).open(); } };
注意,这两种方法的实现都非常相似。我想说,在这两者之间做出决定的最佳方法是考虑代码库的大小,可用于即时编译的可用工具,以及缓存基于角色的已编译软件包。对于我的项目,不仅环境中没有可用的编译器,而且代码库很大(夸张了1.3mb /默认为296kb,加上dojo库),这是不可接受的,因为客户端对保持较低的应用程序负载更感兴趣。次。