Reputation: 1021
EDIT 5
I have back and front end running on LAMP environment accesible with 192.168.80.213/backend
adress.
I try to make a push notification server using nodejs, socket.io and express framework to link back and front end.
My nodejs server is listening on port 3000
while my backend and front end listenning on port 80 both using apache.
Here is my node client :
<script type="text/javascript" src="socket.io-1.4.5.js"></script>
<script type="text/javascript">
var socket = io('http://192.168.80.213:3000/');
</script>
Here is my node server :
const express = require('express')
, app = express()
, http = require('http').Server(app)
, socketIo = require('socket.io')(http)
, cookieParser = require('cookie-parser')
, cookie = require('cookie')
, connect = require('connect')
, expressSession = require('express-session')
, port = 3000
, helmet = require('helmet')
, name = 'connect.sid'
, sessionStore = new expressSession.MemoryStore({ reapInterval: 60000 * 10 })
, sessionSecret = 'VH6cJa7yZSmkRbmjZW#J3%CDn%dt'
, environment = process.env.NODE_ENV || 'development'
;
/** Configuration **/
app.enable('trust proxy');
app.disable('x-powered-by');
app.use(helmet());
app.use(cookieParser());
app.use(expressSession({
'name' : name,
'secret': sessionSecret,
'store' : sessionStore,
'resave': true,
'saveUninitialized': true
}));
app.get('/', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello from node');
});
socketIo.use(function(socket, callback) {
// Read cookies from handshake headers
var cookies = cookie.parse(socket.handshake.headers.cookie);
// We're now able to retrieve session ID
var sessionID;
if (cookies[name]) {
console.log( "cookies['" + name + "'] = " + cookies[name] );
sessionID = cookieParser.signedCookie( cookies[name], sessionSecret );
console.log( "sessionID = " + sessionID );
}else{
console.log( "cookies['" + name + "'] = undefined" );
}
if (!sessionID) {
console.log('ERROR NO SESSION CONNECTION REFUSED !!');
callback('No session', false);
} else {
// Store session ID in handshake data, we'll use it later to associate
// session with open sockets
socket.handshake.sessionID = sessionID;
callback(null, true);
}
});
socketIo.on('connection', function (socket) { // New client
console.log( 'new connection..' );
console.log('user ' + socket.handshake.sessionID + ' authenticated and is now connected.');
});
/** Start server */
http.listen(port);
console.log( "listening on :" + port );
Go to 192.168.80.213:3000
and see 'Hello from node' and cookie['connect.sid'] is set according to screenshot below
And console output :
Now Clearing cache and i'm going to my back end app where is my nodeClient 192.168.80.213/backend
.
connect.sid cookie doesn't exist
And console output :
Why express-session ain't set cookie.sid ? how can i fix that ? I'm new to node and express, i spend many times googling without succes, hope some node masters coul help me !!
regards
Upvotes: 1
Views: 7912
Reputation: 80
I don't have experience using cookie or cookie-parser and am generally new to node, but I had a similar system to authenticate socket connections by accessing server side session variables if that helps at all.
Save the session details inside a variable
var sessionStorage = expressSession({
'secret': sessionSecret,
'store' : sessionStore,
'resave': true,
'saveUninitialized': true
});
let socketIo and app use the storage
socketIo.use(function (socket, next) {
sessionStorage(socket.request, socket.request.res, next);
});
app.use(sessionStorage);
and then inside on connect you can access those session variables using:
socket.request.res.session.[variable name]
Upvotes: 1
Reputation: 5345
I dont know which version of socket.io you are using but after version 1.0 (> 1.0
):
socketIo.use
(See documentation)socket.request
connect.sid
name if you want to use io
name you should set it explicitely (See name option)sessionSecret
not sessionStore
With considering aboves you could use a middleware like following to Authenticate
your sockets:
// every incoming socket should pass this middleware
socketIo.use(function(socket, next) {
var cookies = cookie.parse(socket.request.headers.cookie);
var sessionID = cookieParser.signedCookie(cookies['connect.sid'], sessionSecret);
sessionStore.get(sessionID, function(err, session) {
if ( session && session.isAuthenticated ) {
socket.userId = session.user.id;
return next();
} else {
return next(new Error('Not Authenticated'));
}
});
});
// when connected ...
socketIo.on('connection', function(socket) {
console.log('user ' + socket.userId + ' authenticated and is now connected.')
});
Here i consider you set isAuthenticated
Boolean value and user
on session when users logged in.
Also bear in mind that built in sessionStore
, MemoryStore is not suit for production environment:
The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
So you must consider using another session store like:
Upvotes: 1