node.js - NodeJS : What's the best way to share session between server-rendered views and React app

标签 node.js session reactjs websocket koa

我有一个 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/

相关文章:

PHP 高级安全 session 类

javascript - onChange 事件不会触发 React 的输入字段

javascript - Express.js - 对每个 HTTP 请求执行函数

javascript - 为什么我的循环只循环一次,即使有 3 个项目?

java - 为什么使用 cookie 而不是记录每笔交易

javascript - React 中 this.setState 的异步特性

reactjs - Candidate.toLowerCase 不是函数。 (在 'candidate.toLowerCase()' 中, 'candidate.toLowerCase' 未定义) Material UI

javascript - 将 Node.js 嵌入到流程中

javascript - Mongoose find() 不适用于 $not 查询

php - 如何在php中的while循环中将值添加到单个变量