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 表示的是被截获的对象
分享到:
相关推荐
jdk1.7 64位 免安装版
2022最新版:HEACOOL V1.7主题:加热和空调WordPress主题.rar
2022最新版:CALAFATE V1.7主题:投资组合和Woocommerce Creative主题.rar
prestashop1.7:ماژولپرستاشاپ1.7
windows下 jdk1.7:Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序
板条箱 主要插件: : 这是为真正想要 1.7 Bukkit 版本的人而构建的。
EDM-1.7 EDM 1.7 这是我的主要项目。 我从 2013 年 1 月 10 日开始研究它,从那时起就一直在研究。 请报告您在问题选项卡中看到的代码中的任何错误
2022最新版:GLOBEX V1.7主题:IT解决方案与服务WordPress主题.rar
java jdk1.7源码包,用于centos7使用jdk1.7编译openjdk1.8的 1.7版本
TXE是一个免费的开源文本编辑器,对于日常使用非常有用,它是一个Java学习程序,可以自由更改您的首选项。 它显示了Swing Java,字符串,循环,文件编写器和文件读取器的良好用法。 TXE也非常适合合并到文字处理程序...
$ sudo apt-get install -y virtualenv安装pip类型 $ sudo apt-get install -y python-pip创造环境让我们使用Python 3创建一个环境,输入 $ virtualenv -p /usr/bin/python3 django1.7其中django1.7是环境的名称。...
RAMPS_1.7 适用于3D打印机的Arduino Shield 文档位于: : 论坛讨论位于: : 固件开发位于: :
jquery easyui 1.7中文api,解压后是chm双击直接打开.当前最新版本。
java hashmap 源码
jdk1.7: jdk-7u7-windows-x64(64位), jdk-7u7-windows-i586(32位)。 JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM...
sims_featureScheduler_runs1.7 更多模拟的鲁宾天文台调查 可在以下位置找到运行地址: : 笔记 默认访问次数是2x15s,而不是以前版本中的1x30s。与早期版本相比,这导致访问总数显着减少。 更新了望远镜运动学模型...
ee.j2se-1.7 如何从 JDK 创建 Java 包 将相应的 <linux>.tar.gz 文件下载到文件夹“_download”中 从项目“javadoc.api.extraction”执行启动“ExtractPublicJavaApi.launch” 使用 Ant 在项目“ee.j2se”中运行...
我是不想要分数并且免费的,毕竟是英文原版的,是从官网上下载的。 但是这破地方一定要分数,俺也没得办法。 可以去adobe官网,搜索 PDF 1.7 就能搜到了
Docker操作使用说明v1.7.zip