#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.