PureJS (6.4):利用 proxy 对象实现权限控制和数据校验
利用上一篇文章提到的 proxy 对象,我们还可以实现更多实用的功能。比如本文将探讨的权限控制和数据校验。
权限控制的思路是截获对 page.* 和 api.* 的调用,并利用 session 中记录的用户角色信息进行权限检查;
数据校验还将用到之前的客户端与服务器端共用代码的功能,对数据进行双重检查,以防恶意攻击。
接下来就让我们看看具体的实现吧。
权限控制
这里以对 page.* 的调用为例。基本思路是:
1. 通过正则表达式 /^page./ 和 /^api./ 匹配需要拦截的方法调用
2. 获取参数中的 req (ServletHttpRequest)
3. 获取 session 中的用户角色
4. 如果用户的角色是 admin ,则显示相应页面;否则显示登陆页面
(function() {
var log = pure.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 pure.render("login");
}
}
}
// 利用类似的方法对 api.* 的调用进行权限控制,略
proxy.security.api = { ... }
}());
简单起见,这里仅包含了 admin 一种角色。
启动 mongod 和 PureJS 工程(见附件),输入
http://localhost:8080/,将显示登录页面,在控制台输出(或日志)中也可以看到“Redirect to login page.”的提示。
输入用户名和密码并点击 Sign in 之后,将显示用户列表。
数据校验
在介绍服务器端利用 JQuery 进行页面渲染时,我们提到了服务器端与客户端共用代码的实现(
http://xxing22657-yahoo-com-cn.iteye.com/blog/1113665)。
现在在数据校验功能的实现中我们将再次利用这个功能。
首先编写在服务器端和浏览器中共用的 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_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 };
}
// 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.saveUser 和 浏览器端的 save(...) 中被用到。
客户端的校验是为了给用户更快的反馈,服务器端的校验是为了避免恶意攻击。
代码实现如下:
scripts/app/proxy/validation.js
(function() {
var log = pure.log("proxy.validation");
proxy.validation = { priority: 60 };
proxy.validation.saveUser = {
priority: 100,
expr: /^dbo.users.save$/,
func: function(name, method, args) {
// 获取验证结果
var validated = validator.validateUser(args[0]);
// 验证失败,抛出异常
if (!validated.success) {
log.info(validated.error);
throw validated.error;
}
var data = validated.data;
// 检查用户是否已经存在
// 注意,这里的 this 表示 dbo 对象
if (this.exists(data.name)) {
var msg = "Save User Faild: User already exists.";
log.info(msg);
throw msg;
}
// 通过验证,返回所需的结果
args[0] = data;
return this[method].apply(this, args);
}
}
}());
webapp/js/index.js
$(function(){
// 其他代码,略
function save(user, callback) {
// 获取验证结果
var validated = validator.validateUser(user);
// 验证失败,显示异常
if (!validated.success) {
$("#error").html(validated.error);
return;
}
var data = validated.data;
// 检查用户是否已经存在
for (var i = 0, l = users.length; i < l; ++i) {
if (users[i].name === data.name) {
$("#error").html("User already exists.");
return;
}
}
callback(data);
show();
pure.post({ action: "users.save", params: data });
}
});
可以看到,检查输入是否为空和检查输入参数长度的部分是共用的,但检查用户是否存在的逻辑在客户端和服务器端略有不同。
另外,proxy 对象的 func 中 的 this 表示的是被截获的对象,因此我们可以在 proxy.validation.saveUser 中调用 dbo.exists(name) 来检查用户是否已经存在。
小结
1. 我们可以利用 proxy 对象拦截方法的调用,进行权限和数据的检查
2. 我们可以将服务器和浏览器端共用的代码放在 both 目录下
3. proxy 对象的 func 中 的 this 表示的是被截获的对象
分享到:
相关推荐
《PureJS (6.3):Rhino 中的日志与 Proxy 对象》 在JavaScript的世界里,Rhino是一个非常特别的存在。它是由Mozilla开发的一个开源的JavaScript引擎,它允许JavaScript代码运行在Java平台上,提供了丰富的Java对象...
1. 动态拦截:Proxy 对象是ES6引入的新特性,PandaJS 利用这一特性,提供了一种灵活的方式来拦截并控制对象的访问。通过创建 Proxy 实例,你可以对属性的读取、设置、删除等操作进行拦截,实现数据的动态代理。 2. ...
标题中的“Python开发的MySQL Proxy:Angel Proxy”指的是一个用Python编程语言编写的数据库中间件,它的主要功能是实现MySQL数据库的读写分离。在大型系统中,为了提高数据库的性能和可扩展性,通常会采用读写分离...
Js中Proxy对象 Proxy对象用于定义基本操作的自定义行为,例如属性查找、赋值、枚举、函数调用等。 语法 const proxy = new Proxy(target, handler); target: 要使用Proxy包装的目标对象,可以是任何类型的对象,...
JsProxy是一个强大的在线JavaScript处理工具,它提供了两种主要功能:JavaScript代理(js proxy)和JavaScript打包(js packer)。这两个功能对于前端开发者来说是至关重要的,特别是在处理跨域问题、保护源代码安全...
- **委托和事件**:利用C#的委托和事件机制,代理对象可以监听并处理真实对象的行为。 5. **实际应用**: - **数据缓存**:代理模式可以用来缓存计算结果,避免重复计算。 - **日志记录**:在方法调用前后添加...
Proxy 在前端开发中的应用和实现 Proxy 是 ES6 中引入的一种元编程技术,允许开发者定义基本操作的自定义行为,从而实现对象的代理和拦截。Proxy 的应用范围非常广泛,包括对象的读取、设置、枚举、函数调用等。 ...
通过创建Proxy对象,开发者可以实现对特定图元的读取、编辑和保存,这对于与非AutoCAD系统进行数据交互至关重要。 开发基于OpenDWG的AutoCAD Proxy对象涉及到以下几个关键步骤: 1. **了解OpenDWG库**:OpenDWG库...
dob工具就是为此目的设计的一个高效的数据依赖追踪库,它结合了React,利用Proxy对象来实现这一功能。Proxy是ES6引入的新特性,允许我们创建一个代理对象,对原对象进行拦截和操作,非常适合用于数据观测和响应式...
### C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) #### 重要概念:代理模式 代理模式是一种常用的结构型设计模式,它通过为另一个对象提供一个代理,来控制对该对象的访问。这种模式在软件工程中...
本文将深入探讨如何使用`Proxy`来包裹对象,以实现更灵活的控制和扩展。 ### 1. `Proxy`的基本用法 `Proxy`构造函数接收两个参数:一个是被代理的目标对象,另一个是处理拦截行为的陷阱(handler)对象。陷阱对象...
ArcGIS JS API 跨域配置是指在 JS 开发中遇到的访问本地服务和外网服务的问题,需要使用 Proxy 代理来解决跨域访问文件的问题。ArcGIS 的帮助中已经有了相关的介绍和使用配置。 一、使用代理配置 在 ArcGIS JS API...
解决代理转发post请求失败
本网络课程专注于讲解如何利用Proxy来实现多次后端请求,这对于优化应用程序性能和处理复杂的请求逻辑至关重要。下面,我们将深入探讨Proxy的基本概念、在实现多次后端请求中的作用,以及与课程相关的文件内容。 ...
JavaScript中的Proxy...总结起来,JavaScript中的Proxy对象为开发者提供了强大的灵活性,可以在不改变原始对象的情况下,对对象的访问和操作进行拦截、修改或增强,这在数据验证、缓存、日志记录等方面有广泛的应用。
- 对Proxy调用进行权限控制,限制非授权访问。 ### 维护与升级 - 随着源系统服务的更新,可能需要更新Proxy代码,确保兼容性。 - 使用版本管理,方便回滚到之前的Proxy版本。 总的来说,ABAP调用ABAP Proxy是一种...
在Moer.js中,Proxy被用来实现数据绑定和观察者模式,当数据模型发生变化时,视图能够自动更新,反之亦然,从而实现了双向数据绑定,这是MVVM框架的核心功能之一。 Moer.js的使用流程大致如下: 1. **初始化:** ...
文档控制表格和变更记录部分是项目管理中的标准格式,用于跟踪文档的版本更新和审批流程,这在技术文档中常见,但不包含具体的技术知识点。接下来我们将深入探讨标题和描述中涉及的“sharding-proxy实现分表”这一...