第一部分:问题介绍
简短的说明:我需要将数据从服务器传递到客户端,但这些数据不需要显示在客户端。相反,客户端套接字使用数据来加入正确的房间。转到第二部分:解决方案尝试
长篇故事:
对于我的第一个Web开发项目,我正在尝试创建一个远程演示者(即使用移动设备来控制桌面上的Google幻灯片演示文稿)。
在前端,我一直在使用普通的旧HTMl,CSS和vanilla JS,而后端则涉及NodeJS,Express框架和Socket.io。
以下是用户流程的简要概述:当用户通过桌面上的Google登录进行身份验证时,网站将打开一个套接字连接,该连接会自动加入由套接字ID标识的房间。在用户登录桌面端之后,用户将(现在)将此套接字ID视为可用于在移动端登录的“密钥”。
因此,我有server.js
处理路由和表单操作(即在移动端提交的密钥),如下所示:
// Store all the currently connected web clients
var webClients = [];
// Index route -- home page for website and mobile site
app.get('/', function (req, res) {
// Basic user agent check - test for mobiles
var userAgent = req.headers['user-agent'];
if (/mobile/i.test(userAgent)) {
// Send mobile to the mobile login site
res.sendFile(__dirname + '/pages/mobile.html');
} else {
// Send desktop to the main site
res.sendFile(__dirname + '/pages/index.html');
}
});
// Dealing with secret key input
app.post('/secretKey', function(req, res) {
// Store the secret key in a variable first
var secretKey = req.body.secretKey;
// Check if the secret key matches with any key in the database (current session)
var index = webClients.indexOf(secretKey);
// Send the user to the mobile controls if there is something that matches
if (index != -1) {
res.sendFile(__dirname + '/pages/mobileControl.html');
} else {
res.redirect('/');
}
}
});
不幸的是,我遇到了麻烦。加载移动控件页面后,将在移动端打开另一个套接字实例。为了确保移动设备正在控制正确的演示文稿,我需要让移动端的套接字加入与桌面套接字相同的房间(即具有桌面套接字ID的房间)。因此,我需要将桌面套接字ID传递到移动端,以便移动套接字可以连接到正确的房间。
第二部分:解决方案尝试
我知道其他几位用户已经在SO上提出了类似的问题。例如:
通过这些,我可以总结一些重要的建议:
我查看了Jade和ejs,我不愿意使用这些模板系统,因为我怀疑它们对于我在这里尝试实现的内容可能有点过分 - 只需将字符串从服务器传递到客户端JavaScript而不渲染视图中的字符串。此外,我并不真正需要这些模板系统提供的部分内容,进一步强化了我的信念,即这些可能是过度的。
目前,这个解决方案对我来说最吸引人,因为它似乎是最简单的方法。我可以简单地做一些事情:
var options = {
headers: {
'set-cookie' : roomId=secretKey
}
};
res.sendFile(__dirname + '/pages/mobileControl.html', options);
然后,我可以通过mobileControl.js
之类的操作访问document.cookie
内的Cookie中的数据。但是,我已经读过这种方法存在安全问题,例如跨站点脚本(XSS)攻击。因此,我也不愿意使用这种方法。
除了这三种方法之外,我还研究了实现用户会话,但我认为这不是我的解决方案,因为用户会话可能会在稍后阶段进入以允许登录持续存在。
那么,您认为在这种情况下我应该使用哪种方法?我应该跟2一起调整,并调整cookie的HttpOnly
字段吗?还有其他建议吗?非常感谢!
答案 0 :(得分:2)
如果你不想使用一个完整的模板引擎(尽管我认为这不会超过这个 - 这就是模板引擎的用途),那么只需要替换一个字符串呢?
添加类似
的内容<script>var SECRET_KEY = '{{{SECRET_KEY}}}';</script>
在HTML文件中,流式传输文件而不是发送文件,并使用stream-replace之类的内容将{{{SECRET_KEY}}}
字符串替换为您的密钥。
未经测试的例子:
var fs = require('fs');
var replace = require('stream-replace');
app.post('/secretKey', function(req, res) {
// Store the secret key in a variable first
var secretKey = req.body.secretKey;
// Check if the secret key matches with any key in the database (current session)
var index = webClients.indexOf(secretKey);
// Send the user to the mobile controls if there is something that matches
if (index != -1) {
fs.createReadStream(__dirname + '/pages/mobileControl.html')
.pipe(replace('{{{SECRET_KEY}}}', secretKey))
.pipe(res);
} else {
res.redirect('/');
}
});
然后,您就可以在脚本中使用SECRET_KEY
变量。