`
裴小星
  • 浏览: 265701 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
8ccf5db2-0d60-335f-a337-3c30d2feabdb
Java NIO翻译
浏览量:27842
F3e939f0-dc16-3d6e-8c0b-3315c810fb91
PureJS开发过程详解
浏览量:74318
07a6d496-dc19-3c71-92cf-92edb5203cef
MongoDB Java ...
浏览量:63056
社区版块
存档分类
最新评论

PandaJS 使用说明(1.7):权限控制和数据校验

阅读更多
PandaJS 使用说明(1.7):权限控制与数据校验

  利用上一篇文章提到的 proxy 对象,我们还可以实现权限控制和数据校验。
  权限控制的思路是截获对 page.* 和 api.* 的调用,并利用 session 中记录的用户角色信息进行权限检查;
  数据校验将重用校验代码,在客户端和服务器端对数据进行双重检查。

权限控制

  这里以对 page.* 的调用为例。基本思路是:
  1. 通过正则表达式 /^page./ 和 /^api./ 匹配需要拦截的方法调用
  2. 获取参数中的 req (ServletHttpRequest)
  3. 获取 session 中的用户角色
  4. 如果用户的角色是 admin ,则显示相应页面;否则显示登陆页面

(function() {
	var log = panda.log("proxy.security");

	proxy.security = { priority: 80 };

	// 对 page.* 的调用进行权限控制
	proxy.security.page = {
		priority: 100,
		expr: /^page./,
		func: function(name, method, args) {
			// 获取方法的第二个参数,即 req
			var req = args[1];

			// 读取 session 中的role。返回值是 java.lang.String
			// 加上空字符串转为 JavaScript 中的 String
			var role = req.session.getAttribute("user.role") + "";

			// 如果角色是 "admin",则显示相应页面
			// 否则,显示登录页面
			if (role === "admin") {
				return this[method].apply(this, args);
			} else {
				log.info("Redirect to login page.");
				return panda.render("login");
			}
		}
	}

	// 利用类似的方法对 api.* 的调用进行权限控制,略
	proxy.security.api = { ... }
}());


  简单起见,这里仅包含了 admin 一种角色。
  除此之外,还需要创建文件 webapp/login.html (登陆页面) webspp/js/login.js (向服务器发送用户名和密码的客户端 JS ) 和 scripts/api/auth.js(登录用户名和密码验证),具体内容请查看附件中的相应文件。

  启动 mongod 和 PandaJS 工程(见附件),输入http://localhost/,将显示登录页面,在控制台输出(或日志)中也可以看到“Redirect to login page.”的提示。
  输入用户名和密码并点击 Sign in 之后,将显示用户列表。

数据校验

  首先编写在服务器端和浏览器中共用的 validator 对象:

  webapp/js/both/validator.js
validator = {};

// 校验异常信息
validator.USER_INVALID = "Invalid user data.";
validator.USER_NAME_EMPTY = "Name cannot be empty.";
validator.USER_NAME_TOO_LONG = "Name cannot be longer than 50.";
validator.USER_NAME_FORMAT = "Name format is not conrrect.";
validator.USER_DESC_EMPTY = "Description cannot be empty.";
validator.USER_DESC_TOO_LONG = "Description cannot be longer than 50.";

// 检查 user 对象的方法
validator.validateUser = function(user) {
	// 参数类型错误,可能是恶意攻击
	if (typeof user.name !== "string"
			|| typeof user.desc !== "string") {
		return { success: false, error: validator.USER_INVALID };
	}

	// name 为空
	if (!user.name) {
		return { success: false, error: validator.USER_NAME_EMPTY };
	}

	// name 过长
	if (user.name.length > 50) {
		return { success: false, error: validator.USER_NAME_TOO_LONG };
	}

	// name 格式检查
	if (!/^[A-z][A-z0-9._]*$/.test(user.name)) {
		return { success: false, error: validator.USER_NAME_FORMAT };
	}

	// desc 为空
	if (!user.desc) {
		return { success: false, error: validator.USER_DESC_EMPTY };
	}

	// desc 过长
	if (user.desc.length > 50) {
		return { success: false, error: validator.USER_DESC_TOO_LONG };
	}

	// 提取 name 和 desc;因为对象中可能还有其他不需要的属性
	var data = { name: user.name, desc: user.desc }
	return { success: true, data: data };
}

  这段代码在服务器端的 proxy.validation 对象 和 浏览器端的 save(...) 中被用到。
  客户端的校验是为了给用户更快的反馈,服务器端的校验是为了避免恶意攻击。
  代码实现如下:

  scripts/app/proxy/validation.js
(function() {
	var log = panda.log("proxy.validation");

	proxy.validation = { priority: 60 };

	// 创建或更新 user 时,检查 user 数据
	proxy.validation.saveUser = {
		priority: 100,
		expr: /^dbo.users.(add|update)$/,
		func: function(name, method, args) {
			var validated = validator.validateUser(args[0]);

			if (!validated.success) {
				log.info(validated.error);
				throw validated.error;
			}

			args[0] = validated.data;

			return this[method].apply(this, args);
		}
	};

	// 创建 user 时,检查用户是否已经存在
	proxy.validation.addUser = {
		priority: 80,
		expr: /^dbo.users.add$/,
		func: function(name, method, args) {
			var user = args[0];

			if (this.exists(user.name)) {
				var msg = "The user already exists.";
				log.info(msg);
				throw msg;
			}

			return this[method].apply(this, args);
		}
	};
}());


  webapp/js/index.js
$(function(){
	// 其他代码,略

	function save(action, user) {
		// 验证 user 数据有效性
		var validated = validator.validateUser(user);

		if (!validated.success) {
			$("#error").html(validated.error).show();	
			return;
		}

		// 向服务器端发送请求
		var req = { action: action, params: validated.data };
		panda.post(req, show, function(error){
			$("#error").html(error).show();	
		});
	}

	function show(users) { ... }
});

  可以看到,检查输入是否为空和检查输入参数长度、格式的部分是共用的,但检查用户是否存在的逻辑只存在于服务器端的 proxy 对象。
  另外,proxy 对象的 func 中 的 this 表示的是被截获的对象,因此我们可以在 proxy.validation.saveUser 中调用 dbo.exists(name) 来检查用户是否已经存在。
  此外,还需要实现 dao.users.exists(name) 方法,并在 index.html 中添加对 webapp/js/both/validator.js 的引用,详细内容请查看附件中的相应文件。

小结

  1. 我们可以利用 proxy 对象拦截方法的调用,进行权限和数据的检查
  2. 我们可以将服务器和浏览器端共用的代码放在 both 目录下
  3. proxy 对象的 func 中 的 this 表示的是被截获的对象
3
2
分享到:
评论

相关推荐

    JDK1.7.0.51 免安装版

    通过使用JDK1.7.0.51免安装版,开发者可以在不修改系统环境变量的情况下,方便地在本地工作环境中配置和使用Java 7开发环境,这对于多项目管理或在不同Java版本间切换非常有帮助。同时,由于其64位特性,可以充分...

    文件校验工具1.7

    《文件校验工具1.7:批量操作与高效文件验证》 在数字化时代,文件的传输和存储变得日益频繁,确保文件的完整性和安全性显得至关重要。"文件校验工具1.7"是一款专为此目的设计的专业软件,它提供了丰富的功能,如...

    《jQuery UI 1.7: jQuery用户界面库》[PDF]

    Build highly interactive web applications with ready-to-use widgets from the jQuery User Interface library

    CratesPlus_1.7:CratesPlus for Bukkit 1.7

    《CratePlus_1.7:Bukkit 1.7 版本的板条箱插件详解》 在 Minecraft 的服务器运营中,为了让游戏体验更加丰富多样,许多管理员和开发者会借助各种插件来增强游戏的功能性和趣味性。其中,“CratesPlus_1.7”是一款...

    EasyUI操作说明1.7.chm.zip

    这个"EasyUI操作说明1.7.chm.zip"压缩包包含了EasyUI 1.7版本的中文API文档,方便开发者查阅和理解其功能与用法。CHM(Compiled Help Manual)文件是一种Windows下的帮助文档格式,双击即可直接打开阅读。 EasyUI ...

    prestashop1.7:ماژولپرستاشاپ1.7

    标题 "prestashop1.7:ماژولپرستاشاپ1.7" 指的是 PrestaShop 电子商务平台的1.7版本中的模块开发。PrestaShop 是一个流行的开源电子商务解决方案,用于在线商店的建设和管理。在这个特定的讨论中,重点...

    2022最新版:HEACOOL V1.7主题:加热和空调WordPress主题.rar

    HEACOOL V1.7是一款专为加热和空调服务行业设计的WordPress主题,它集成了最新的设计趋势和功能,旨在为用户提供一个专业且用户友好的在线平台。这款主题在2022年进行了更新,以适应不断变化的网站需求,提供更好的...

    2022最新版:CALAFATE V1.7主题:投资组合和Woocommerce Creative主题.rar

    下载并解压“2022最新版:CALAFATE V1.7主题:投资组合和Woocommerce Creative主题.rar”后,将主题文件上传至WordPress后台的主题管理界面,然后点击“激活”即可开始使用。为了充分利用所有功能,还需要安装和配置...

    EDM-1.7:电火花加工 1.7

    GUI设计则让操作员能够直观地交互和控制设备,而数据处理算法则负责解析和分析加工过程中的各种参数,如电流、脉冲频率、电极位置等。 电火花加工的核心在于放电控制,这通常涉及到精确的时间控制和电压调节。在...

    RAMPS_1.7:适用于3D打印机的Arduino Shield

    **RAMPS 1.7: 3D打印机的Arduino Shield详解** RAMPS 1.7是一种专门为3D打印机设计的Arduino扩展板,全称为Reprap Modular Arduino普适平台(Reprap Prusa I3 Modular Arduino Platform Shield)。它是基于Arduino ...

    南方全站仪传输软件压缩包V1.7

    南方全站仪传输软件是专为使用南方全站仪的用户设计的一款实用工具,主要用于将全站仪的数据传输到电脑上进行分析、处理和存储。这个压缩包"南方全站仪传输软件压缩包V1.7"包含了软件的最新版本,能够帮助用户更高效...

    ArcGIS超级工具1.7安装及说明.zip

    《ArcGIS超级工具1.7:安装指南与详解》 ArcGIS是一款强大的地理信息系统软件,由Esri公司开发,广泛应用于地图制作、地理数据分析、空间建模等多个领域。ArcGIS超级工具则是该软件的一个扩展模块,它提供了更多...

    jdk1.7 + 使用说明.zip

    **JDK 1.7 使用指南** 在计算机科学领域,Java Development Kit (JDK)...请参考提供的`JDK环境配置说明.docx`文档,获取更详尽的配置步骤和使用指导。在安装和配置过程中遇到任何问题,都可以在相关平台留言寻求帮助。

    USBOOT 1.7

    《USBOOT 1.7:打造高效USB启动盘的实用工具》 USBOOT 1.7是一款专门用于制作USB启动盘的工具,它为用户提供了简单便捷的方式来将普通USB设备转化为能够引导计算机启动的设备。在当今信息化社会,无论是系统安装、...

    pdf1.7最新标准

    6. **安全性**:PDF 1.7提供了权限管理(PDF加密)和认证(数字签名)机制,以保护文档的隐私和完整性。 7. **元数据**:PDF文档可以包含XML格式的元数据,用于描述文档的信息,如作者、标题、创建日期等,方便管理...

    Jquery1.7使用以及讲解

    在jQuery 1.7中,`$.ajax()`方法也得到了增强,增加了`beforeSend`, `statusCode`和`xhrFields`选项,提供了更精细的控制和自定义功能。 ### 5. `$.each()` 的优化 `$.each()` 函数在处理大型数组时的性能得到了...

    杰奇1.7 安装说明,视频教程

    4. `授权说明.txt`:这个文件解释了软件的许可条款和使用规定,确保你在使用杰奇1.7时遵守法律。 5. `第一课程序安装.wmv`:这是一个视频教程,直观地演示了安装过程。如果你更喜欢通过观看视频学习,那么这个资源...

    ArcGIS超级工具1.7以及安装说明.zip

    **ArcGIS超级工具1.7** 是一个专为地理信息系统(GIS)专业人士设计的强大扩展,它增强了Esri的ArcGIS...通过详细阅读和遵循安装说明,用户可以顺利安装并开始使用这个强大的工具扩展,进一步提升其GIS工作流程的效率。

Global site tag (gtag.js) - Google Analytics