我有一个 NodeJS (Koa) 服务器应用程序,它从服务器渲染页面,即 nunjucks/jade/etc。登录页面也是服务器渲染的。登录后,将创建 cookie。
现在我正在构建一个 react 应用程序,它将嵌入到安全页面中(用户登录后)。让 react 应用程序使用用户当前登录的 session 向服务器发出安全的 Http/Websocket 请求的最佳方法是什么?
目前,我将 sessionId 注入(inject)到加载 React 应用程序的服务器渲染页面的脚本标记中。所以...
服务器:
var session = require('koa-generic-session');
app.use(session({
store: redisStore(...)
}));
app.use(function*(next) {
this.state.sessionIdFromServer = this.sessionId;
return yield next
});
客户:
<script>
var sessionId = {{sessionIdFromServer}};
</script>
...
<div id='app'> react app loads here </div>
然后我在客户端 HTTP/WebSocket 请求(特别是 websocket)中使用该 sessionId 变量。
对于客户端发出的每个请求(在套接字的情况下传递 sessionId),服务器在完成请求之前基本上会检查 Redis session 存储以查看该 session 是否仍然有效(即未过期或未注销)。
这是一种可行/足够安全的方法吗?
最佳答案
对,我应该做的就是在您的 session 中使用 cookie。这样,任何前端 AJAX 调用(包括 WebSocket)都将使用请求 header 中的 cookie。
通过在 Cookie 上设置 HTTP Only
设置,前端 JavaScript 无法修改(或访问) session Cookie,但浏览器仍会在任何传出请求中使用它。
在我看来,这是使用 session id 最安全的方式,前端不需要首先知道 cookie 的存在。
如果 koa 中的 session 不再存在,您会自动知道用户也已注销。
我为此做了一个小例子(下面有一个 Github 链接):
首先是index.js
:
'use strict';
const session = require('koa-session');
const koa = require('koa');
const websockify = require('koa-websocket');
const route = require('koa-route');
const app = websockify(koa());
app.keys = ['some secret hurr'];
const sessionStore = session(app);
app.use(sessionStore);
app.ws.use(sessionStore);
app.use(route.all('/', function* (next) {
// ignore favicon
if (this.path === '/favicon.ico') return;
let n = this.session.views || 0;
this.session.views = ++n;
yield next;
}));
app.ws.use(route.all('/', function* (next) {
this.websocket.on('message', (message) => {
let n = this.session.views || 0;
this.session.views = ++n;
if (message === 'ping') {
// Return the amount of sessions (n) when the client sends ping
this.websocket.send('pong ' + n);
}
});
yield next;
}));
app.use(require('koa-static')('./public'));
app.listen(3000);
console.log('listening on port 3000');
然后是index.html
:
<html>
<script>
var ws = new WebSocket("ws://localhost:3000/");
ws.onopen = function() {
// Sends a message
ws.send("ping");
};
ws.onmessage = function(e) {
// Receives a message.
alert(e.data);
};
ws.onclose = function() {
alert("closed");
};
</script>
</html>
我已将所有这些放入一个工作示例中 on GitHub .
关于node.js - NodeJS : What's the best way to share session between server-rendered views and React app,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39810977/