I am implementing a MongoStore for use in session storage within my Node.js/Express application, however it looks as if none of the sessions are actually being stored in the database. (The MongoDB does not even have the db.session).
Socket.io 'authorization' takes the incoming data, and crosschecks the sent sessionID, however it keeps returning empty.
Hope someone could shed some light on any issues?
var express = require('express');
var bodyParser=require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var utils = require("express/node_modules/connect/lib/utils");
var parseSignedCookie = utils.parseSignedCookie;
var cookie = require('cookie');
var app = express();
app.use(bodyParser());
app.use(cookieParser());
var sessionStore = new MongoStore({
db: 'express',
host: 'localhost',
port: 27018,
collection: 'session',
auto_reconnect:true
});
app.use(session({
cookie: { maxAge: 5000 } ,
secret: "session secret",
store: sessionStore
}));
function checkSession(req,res,next){
if(req.session.user){
next();
}
else {
req.session.error = "Get Outta here!";
res.redirect('/');
}
}
app.get('/', function(req, res){
res.sendfile('./index.html');
});
app.post('/',function(req,res){
if(req.body.name){
req.session.user=req.body.name;
res.redirect('/info');
}
else {
req.session.error = "Auth Failure";
res.redirect('back');
}
});
app.get('/info', checkSession, function(req,res){
if(req.headers.cookie){
var session_id = utils.parseSignedCookie(req.headers.cookie, 'session secret');
console.log(session_id);
console.log("true");
res.sendfile('./info.html');
}
else {
console.log("false");
res.redirect('/');
}
});
var http = require('http').Server(app);
http.listen(80, function(){
console.log('listening on *:80');
});
var io = require('socket.io').listen(http);
You're not using your sessionStore anywhere. Try this:
app.use(session({
store: sessionStore,
cookie: { maxAge: 5000 } ,
secret: "session secret"
}));
Related
I seem to not be able to share sessions between express and socket io . It works when on localhost but not when on my server. There is something I am missing.
The data I store in socket.handshake.session ('age' here) is not saved on the express side.
My app.js goes like this:
var cookieParser = require('cookie-parser');
var session = require('express-session');
var app = express();
app.use(cookieParser()); // read cookies (needed for auth)
var sessionMiddleware = session({
secret: 'keyboard cat',
resave: true,
name: 'sessionId',
saveUninitialized: true,
cookie: { maxAge: 60000 },
// store: new redisStore({ host: 'localhost', port: 6379, client: redisClient, ttl: 86400 }),
});
app.use(sessionMiddleware);
app.set("sessionMW", sessionMiddleware);
module.exports = app;
My bin\www goes like this:
var app = require('../app');
var debug = require('debug')('testserver:server');
var http = require('http');
var sharedsession = require("express-socket.io-session");
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var session = app.get("sessionMW")
io.use(sharedsession(session, {autosave:true}));
server.listen(port);
I then have a serverEvent.js that goes like this:
var serverEvents = module.exports = function(io){
io.sockets.on('connection', function (socket) {
...
...
...
socket.on('updateAgeSession', function (message) {
socket.handshake.session.age = "18";
socket.handshake.session.save();
console.log(socket.handshake.session);
})
})
}
And finaly I have this index.js for my routes:
module.exports = function (app, passport) {
// show the home page (will also have our login links)
app.get('/', function (req, res, next) {
res.cookie('mycookies', 'express');
res.cookie('age', req.session.age);
cookie1= req.cookies;
console.log(req.session);
console.log(req.sessionID);
console.log(req.sessionStore.sessions);
if (req.session.views) {
req.session.views++;
console.log(req.session.views);
} else {
req.session.views = 1
console.log(req.session.views);
}
if(req.session.age){
console.log("OOOOOOOOOOOOOOOOOO");
} else {
console.log("XXXXXXXXXXXXXXXXXXXXXX");
}
res.render('homePage'); // ejs template
});
}
So my problem is that after I enter that Im over 18 when I refresh the page , the req.session.age will be undefined, but only when my code runs on server, it does work on localhost. I dont get it.
Please help
For anyone that might have got the same problem I had, here is the solution :
I also have a client side code that goes like this :
var socket = io.connect("http://ip:3000");
var globalVar = [];
// Sent on connection/searchValidatedFromClient by server
socket.on("loadHomePageFromServer", function(message) {
...}
Problem was io.connect("http://ip:3000");.
By changing it to io.connect("http://namesite.com"); or io.connect("http://ip:80");, it works!
I have a little probleme with my Nodejs application. I want protect my forms with csrf token, but it's not work. I have an error like
ForbiddenError: invalid csrf token
POST http://localhost:3000/addfile 403 (Forbidden)
I want to create csrf token for all requests. I can create csrf token, but if I use the methods like : POST/PUT or DELETE it's not work.
I don't understand why I have this error. Thanks for yours answers.
app.js
var express = require("express");
var bodyParser = require("body-parser");
var mongoose = require('mongoose');
var fs = require('fs');
var path = require('path');
var logger = require('morgan');
var expressValidator = require('express-validator');
var csrf = require('csurf');
var session = require('express-session');
var passport = require('passport');
var PORT = 3000;
var config = require('./config/database');
var app = express();
// Connexion to MongoDb
mongoose.connect(config.database, function(err) {
if(err){
console.log(err);
}
else{
console.log("Connected to MongoDb");
}
});
// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(expressValidator());
app.set('views',path.join(__dirname, ''));
app.set('view engine','pug');
app.use(express.static(path.join(__dirname, '')));
app.disable('x-powered-by');
app.use(session({
name: 'SESS_ID',
secret: config.secret,
resave: true,
saveUninitialized: true,
cookie: {
secure: false,
httpOnly: true,
maxAge: 5*60*1000 } //15minutes*60sec*1000ms
//cookie: {secure: false} //https = true, http=false
}));
app.use(csrf());
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.use(function(req, res, next) {
res.locals._csrf = req.csrfToken();
next();
});
app.use('/', require('./routes/fileRoutes'));
app.use('/', require('./routes/authRoutes'));
app.listen(PORT,function(){
console.log("Server started at the port " + PORT);
});
routes/fileRoutes.js
app.get('/',function(req,res){
File.find(function(err, files){
res.render('views/layout',{files:files});
});
});
app.post('/addfile',upload,function(req,res){
if (req.fileValidationError) {
return res.end("Error PDF");
} else {
for (var i = 0; i < req.files.length; i++)
{
var files = new File ();
files.fieldname= req.files[i].fieldname;
files.originalname= req.files[i].originalname;
files.encoding= req.files[i].encodin;
files.path= req.files[i].path;
files.save(function(err, data){
});
}
res.redirect('/');
}
});
layout.pug
form#uploadForm(enctype='multipart/form-data', action='/addfile', method='post')
input(type='hidden', name='_csrf', value=_csrf)
input(type='file', name='userPhoto', multiple='')
input(type='submit', value='Upload Image', name='submit')
input#random(type='text', name='random')
I see you have:
input(type='hidden', name='_csrf', value=_csrf)
What is the value for if you console.log(_csrf)? I also noticed you didn't put that one in quotes.
Code:
Express.js
'use strict';
module.exports = function(app, io, server) {
var express = require('express');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(methodOverride('X-HTTP-Method-Override'));
// Redis
const redis = require('./utils/redis.js')();
app.set('redis', redis);
let isSessionCreated = false;
app.use('*', (req, res, next) => {
if(!isSessionCreated) {
isSessionCreated = true;
require('./middleware/sessionConfig.js')(app);
next();
}
});
// Passport
require('./middleware/passport.js')(app);
// Start Socket
require('./middleware/startSocket')(app, io);
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/dist'));
// Start Webpack
require('./webpack/startWebpack.js')(app);
// routes ==================================================
require('./routes/routes')(app); // configure our routes
require('../config/webpack.dev.js');
}
redis.js
'use strict';
const redis = require('redis'),
session = require('express-session'),
redisStore = require('connect-redis')(session),
redisClient = redis.createClient(),
uuid = require('uuid'),
cookieParser = require('cookie-parser');
module.exports = function() {
console.log('Redis started');
// Connects to Redis Store
const sessionStore = new redisStore({
host: '127.0.0.1',
port: 6379,
client: redisClient,
ttl : 3600000
});
redisClient.on('error', (err)=> {
console.log('could not connect ', err);
});
// Checks for Redis Connection
redisClient.on('connect', ()=> {
console.log('redis connected');
});
return {
set: function(obj) {
console.log('set called: ', obj);
redisClient.set(obj.id, obj.token);
},
sessionStore
}
}
sessionConfig.js
'use strict';
module.exports = function(app) {
const cookieParser = require('cookie-parser'),
session = require('express-session'),
uuid = require('uuid');
// Sets up Express Session
app.use(cookieParser());
console.log('session created');
let redis = app.get('redis');
app.use(session({
name: 'irelief',
secret: 'irelief',
store: redis.sessionStore,
cookie: {
cookieName: 'xyz',
httpOnly: false,
secret: 'irelief',
secure: false,
maxAge: 360000000
},
genid: function(req) {
return uuid.v4();
},
saveUninitialized: false,
resave: true,
rolling: true
}));
}
OUTPUT OF req.session on app.get('/', (req, res))
session: Session {
cookie:
{ path: '/',
_expires: 2017-07-30T22:38:34.653Z,
originalMaxAge: 360000000,
httpOnly: false,
cookieName: 'xyz',
secret: 'irelief',
secure: false } }
I have tried all that was said across any communities, nothing helps so far.
The same problem persists with passport.js
Any help will be awesome
Trying to get sessions set up with Redis. I have my Redis DB in a dokku container, linked to my app (also in a dokku container). I keep getting a session undefined.I've stripped things back to the bare minimum, also checked the order in which things are run. I still get an undefined.
I've read here 'session' is undefined when using express / redis for session store and Express js session undefined to no avail.
I shouldn't need to use cookie-parser, as expression-session has cookie stuff in it, and the docs say cookie-parser can cause problems with expression-session.
var express = require('express');
var session = require('express-session');
var redisStore = require('connect-redis')(session);
var bodyParser = require('body-parser');
var app = express();
app.set('port', (process.env.PORT || 5000));
var redisURL = 'redis://xxxxx:1234567#bar-redis-foo:6379';
var store = new redisStore({ url: redisURL });
app.use(session({
secret: 'ssshhhhh',
store: store,
saveUninitialized: true,
resave: true
}));
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.get('/', function(req, res, next) {
console.log(req.session); // Logs Undefined
res.send('Hello');
});
Check your redis connection and run again. Sample code is following line.
"use strict";
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const RedisStore = require("connect-redis")(session);
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(session({
secret: "$kx(Fj$uB!Ug!#jCkguFmc6f7t<c-e$9",
resave: false,
saveUninitialized: true,
store: new RedisStore({
url: "redis://:********#pub-redis-12766.eu-central-1-1.1.ec2.redislabs.com:12766",
ttl: 5 * 60 // 5 minute (Session store time)
})
}));
app.use(function (request, response, next) {
let path = request.originalUrl;
if (request.session.user) {
request.session.reload(function (err) { //session expire time regenerate
if (!err) {
next();
} else {
response.redirect('/login');
}
});
} else {
if (path == '/login') {
next();
} else {
response.redirect('/login');
}
}
});
app.get('/', function(request, response) {
if (request.session.user) {
response.send(request.session.user);
} else {
response.redirect("/login");
}
});
app.get('/login', function(request, response) {
if (request.session.user) {
response.redirect("/");
} else {
request.session.user = {username: "halil"}; //custom key {user} and custom data {username: "halil"}
}
response.send('Login');
});
app.get('/logout', function(request, response) {
if (request.session.user) {
request.session.destroy();
response.redirect("/login");
} else {
response.redirect("/login");
}
});
app.listen(app.get('port'), function () {
console.log('App is working on port: ' + app.get('port'));
});
I'm using express and socket.io and I want to share the express session between the two, with each one being on a different Node instance (localhost:3000 and localhost:8000). So far, express will create the session and the cookie created, however socket.io only picks up the 'io' cookie, not the express cookie. Can anyone show mw here my error is? I'm using express 4.x and socket.io 1.x.
Express config (localhost:3000):
var cookieParser = require('cookie-parser')
, session = require('express-session')
, bodyParser = require('body-parser')
, express = require('express')
, redis = require('redis')
, RedisStore = require('connect-redis')(session);
module.exports = function (app, passport) {
app.use(express.static('./static'))
app.use(cookieParser("thisismynewsecret"));
app.use(session({
//passport: passport,
name: 'sid',
//key: 'express.sid',
secret: 'thisismynewsecret',
saveUinitialized: true,
resave: true,
store: new RedisStore({ client: redis.createClient() }),
cookie: {
httpOnly: true,
path: '/',
secure: false
}
}));
app.use(passport.initialize());
app.use(passport.session());
// all environments
app.set('port', process.env.PORT || 3000)
app.set('views', './views')
app.set('view engine', 'jade')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(require('method-override')());
app.use( require('express-subdomain-handler')({ baseUrl: 'localhost', prefix: 'myprefix', logger: true }) );
}
});
socket.io (localhost:8000):
var fs = require('fs');
var session = require('express-session');
var cookie = require('cookie');
var cookieParser = require('cookie-parser');
var sessionStore = require('connect-redis')(session);
var server = require('http').Server(function(req, res) {
fs.readFile(__dirname + '/views/JAMinit.html', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
}
else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
}
});
}).listen(8000);
var io = require('socket.io')(server);
io.use(function(socket, next) {
var data = socket.handshake || socket.request;
if (data.headers.cookie) {
data.cookie = cookie.parse(cookieParser.signedCookie(data.headers.cookie, 'thisismynewsecret'));
console.log(data.cookie);
console.log('data.cookies ( %s )', JSON.stringify(data.cookie));
if (data.cookie.sid) {
data.sid = data.headers.cookie.sid;
sessionStore.get(data.headers.cookie.sid, function(err, session) {
data.session = session;
});
}
}
next();
});
Check out express.io, it combines express and socket.io and has automatic session support.