NodeJS: каков наилучший способ разделить сеанс между отображаемыми на сервере представлениями и приложением React

#node.js #session #reactjs #websocket #koa

#node.js #сеанс #reactjs #websocket #koa

Вопрос:

У меня есть серверное приложение NodeJS (Koa), которое отображает страницы с сервера, например, nunjucks / jade / etc. Страница входа также отображается на сервере. При входе в систему создаются файлы cookie.

Сейчас я создаю приложение react, которое будет встроено в защищенную страницу (после входа пользователя в систему). Каков наилучший способ заставить это приложение react отправлять безопасные Http / Websocket запросы на сервер, используя текущий сеанс пользователя, вошедшего в систему?

В настоящее время я вводю идентификатор сеанса в тег сценария отображаемой на сервере страницы, где загружается приложение 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>
  

Затем я использую эту переменную SessionID в своих запросах HTTP / WebSocket на стороне клиента (в частности, websocket).

Для каждого запроса, выполняемого клиентом (передача идентификатора сеанса в случае сокетов), сервер в основном проверяет хранилище сеансов Redis, чтобы убедиться, что этот сеанс все еще действителен (т. Е. Не Истек или Не вышел из системы), прежде чем выполнять запрос.

Является ли это возможным / достаточно безопасным подходом?

Ответ №1:

Правильно, то, что я должен сделать, это просто использовать файлы cookie для вашего сеанса. Таким образом, любые интерфейсные вызовы AJAX (включая WebSocket) будут использовать cookie в заголовках запроса.

С HTTP Only настройкой, установленной для файла cookie, никакой интерфейсный JavaScript не может изменять (или получать доступ) файл cookie сеанса, но он по-прежнему используется браузером при любом исходящем запросе.

На мой взгляд, это самый безопасный способ использования идентификатора сеанса, при этом интерфейсу в первую очередь не нужно знать о существовании файла cookie.

Если сеанс в koa больше не существует, вы автоматически узнаете, что пользователь также вышел из системы.

Я привел небольшой пример для этого (ссылка на 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>
  

Я включил все это в рабочий пример на GitHub.