Express-session. Session not persisting - node.js

Session data is not persisting for multiple calls. It is going through localhost. I have tried making the cookie not secure. Every call has the value of 1 and it never changes. Using latest versions of all packages. Please help me
// JS
$.ajax({
type: "GET",
url: "http://localhost:8080/test/",
success: (result) => { console.log(result); }
});
// NODE
var express = require("express");
var path = require('path');
var cors = require('cors');
var hash = require('object-hash');
var session = require('express-session');
var app = express();
app.use(express.json());
app.use(cors());
app.use(express.urlencoded({extended: true}));
app.use(session({
resave: false,
saveUninitialized: true,
secret: 'keepThemSweatyKidsAway',
cookie: {
secure: false
}
}));
app.use((req, res, next) => {
if (!req.session.views) {
req.session.views = 0;
}
req.session.views = req.session.views + 1;
next();
});
app.get('/test/', function (req, res, next) {
console.log(req.session);
res.send('you viewed this page ' + req.session.views + ' times');
});
app.listen(PORT, () => {
console.log("Server listening on: https://sweaty-kids.herokuapp.com:%s", PORT);
});

Related

Protection csrf Nodejs Form

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.

Node js (Express ) express.static is not working

I am working on a small app in which I just logging user using Gmail account. Problem is when user login successfully into app there is redirect to other page which gives error 404.
Directory hierarchy is like enter image description here
And Ejs files are in view folder
I When User login by google account It should be Redirected to Welcome page But it gives an error Page not found.
Default page code is below
"use strict"
const path=require("path");
const express=require("express");
const session=require("express-session");
const bodyParser=require("body-parser");
const passport = require("passport");
const db =require("./DbConnection/findCollection");
const auth = require("./auth");
const compression = require("compression");
var appDir = path.dirname(require.main.filename);
const app=express();
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended:true}));
//enable gzip
app.use(compression());
//enable session storage
//TODO: add connect-mongo as session storage
app.use(session({
resave: false,
saveUninitialized: false,
secret:"keyboardcat",//config.get("SECRET"),
signed: true
}));
app.all("*", (req, res, next) => {
console.log("request: " + req.url);
next();
});
//OAuth
app.use(passport.initialize());
app.use(passport.session());
app.use(auth.router);
function respond(req, res) {
return function (err, data) {
if (err) {
return res.status(400).send(err);
}
res.header("Content-Type", "application/json");
res.send(data);//JSON.stringify(data, null, 2));
};
}
function render(req,res,file,data){
res.render("master.ejs", { content: file, req: req, data: data});
}
app.get("/",(req,res,next)=>{
if(req.user){
console.log("Path is "+appDir);
// res.redirect("/views/welcome");
res.redirect("/welcome");
}
else{
console.log("Path is "+appDir);
render(req, res,"login.ejs");}
});
app.use("/views", express.static(__dirname + '/views'))
app.all("*", (req, res) => {
res.status(404).send("Page was not found, sorry!");
});
var server = app.listen(process.env.PORT || 3000, process.env.IP || "0.0.0.0", () => {
var address = server.address();
console.log(`[${(new Date().toString()).substr(0, (new Date().toString()).indexOf(" ("))}] Server started on http://${address.address}:${address.port}`);
});
To make the express able to load the view file, you should put
app.set('views', path.join(__dirname, 'views'));
instead of
app.use('/views', express.static(__dirname + '/views'));

Express session is undefined when accessing from different route?

Im trying to implement infinite scroll. In my first route I load 5 elements from the data base and store the id of the last seen item. To load more data getNextHomeContent is called, but for some reason req.session.lastseen is undefined.
server.js
var express = require('express');
var session = require('express-session');
var app = express();
var mongoose = require('mongoose');
var logger = require('morgan');
var bodyParser = require('body-parser');
var cors = require('cors');
//imports database configuration
var databaseConfig = require('./config/database');
//defines route file to use
var router = require('./app/routes');
//connect to datbase
mongoose.connect(databaseConfig.url);
app.listen(process.env.PORT || 8080);
console.log("App listening on port 8080");
app.use(bodyParser.urlencoded({ extended: false })); // Parses urlencoded bodies
app.use(bodyParser.json()); // Send JSON responses
app.use(logger('dev')); // Log requests to API using morgan
app.use(cors());
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'keyboard cat',
cookie: {
maxAge: 60000,
secure: false
}
}));
router(app);
And here is my controller for my routes in homeCtrl.js
exports.getHomeContent = function(req, res, next) {
req.session.lastseen = null;
homeContent.find({})
.sort({
"_id": -1
})
.limit(5)
.exec(function(err, content) {
if (err) {
res.send(err);
}
var last = content.slice(-1);
req.session.lastseen = last[0]._id;
console.log("lastseen first is " + req.session.lastseen);
res.json(content);
});
}
exports.getNextHomeContent = function(req, res, next) {
console.log("lastseen is " + req.session.lastseen);
homeContent.find({
"_id": { "$lt": req.session.lastseen }
})
.sort({
"_id": -1
})
.limit(5)
.exec(function(err, content) {
if (err) { res.send(err); }
console.log("WTF:" + content.slice(-1));
var lastitem = content.slice(-1);
req.session.lastseen = lastitem[0]._id;
res.json(content);
});
}
When get Home content runs, req.session.lastname is set to the ID of the last item. However req.session.lastitem becomes undefined when getNextHomeContent() runs. Can anyone help me with this?
Thanks!!

Express.js session undefined. Redis

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'));
});

Inserting Facebook login and Geolocation data into MongoDB

I'm currently working on a project where a User logs in with Facebook, sees a map with their location pinpointed, and then can see their friends who have also logged in on the map (with the distance).
The next step is to store this data in a database.
As I'm fairly new to using MongoDB, I would like some guidance on how to approach taking the Facebook login/Geolocation data and inserting it into the database. I'm comfortable with inputting BSON objects into the database manually from the command line, but I cannot seem to find the best way of doing this in my code.
The code is below - it would really help to have some guidance on first steps to getting the post data and putting it into the MongoDB database. Thank you!
var express = require('express')
var passport = require('passport')
var util = require('util')
var FacebookStrategy = require('passport-facebook').Strategy
var logger = require('morgan')
var session = require('express-session')
var sessionStore = require('sessionstore');
var bodyParser = require("body-parser")
var cookieParser = require("cookie-parser")
var methodOverride = require('method-override');
var port = process.env.PORT || 3000
var io = require('socket.io')(http);
var http = require('http').Server(app);
var markers = [];
var server = require('http').createServer(app);
var passportStrategy = require('../utils/passport-strategy');
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var FACEBOOK_APP_ID = "*";
var FACEBOOK_APP_SECRET = "*";
passport.use(passportStrategy.facebook);
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
var sessionData = session({
store: sessionStore.createSessionStore(),
secret: "your_secret",
cookie: { maxAge: 2628000000 },
resave: true,
saveUninitialized: true
});
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
}
));
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(sessionData);
app.use(logger("combined"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(methodOverride());
app.use(session({
secret: "keyboard cat",
saveUninitialized: true, // (default: true)
resave: true, // (default: true)
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index', { user: req.user });
});
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
app.get('/login', function(req, res){
res.render('login', { user: req.user });
});
app.get('/auth/facebook',
passport.authenticate('facebook'),
function(req, res){
});
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
app.get('/mapjs', function(req, res){
res.sendFile(__dirname + '/public/map.js');
});
// Socket markers start
io.on('connection', function(socket) {
console.log('a user connected');
socket.on('marker', function(data) {
data.socketId = socket.id;
markers[socket.id] = data;
console.log('marker latitude: ' + data.lat + ', marker longitude:' + data.lng);
socket.broadcast.emit('show-marker', data);
});
// socket.on('show-marker', )
socket.on('show-user-location', function(data) {
socket.broadcast.emit('show-user-location', data);
});
});
app.listen(port, function(){
console.log('five minute catch up is on port 3000');
});
// socket markers end
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
module.exports = server;
can you strip this down so that you are doing only the insertion of some static data before connecting it up to facebook and having sockets in there. Every extra bit of code will get in the way of knowing whether what change you try is actually doing what you want.
Regarding the best way to insert data programmatically in mongodb, I believe this is the relevant part of the documentation:
http://docs.mongodb.org/manual/core/write-operations-introduction/
db.users.insert(
{
name: "sue",
age: 26,
status: "A"
}
)

Resources