How to send cookies to client from node/express server? - node.js

I am having the hardest time sending cookies from my nodejs server to my browser. Below is my index.js (server side) code:
app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use(
cors({
origin: "http://localhost:3000",
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
credentials: true
})
);
let port = process.env.PORT;
if (port == null || port == "") {
port = 5000;
}
mongoose.connect(process.env.ATLAS_URI).then(console.log("MongoDB Connection Success")).catch(err => console.log("MongoDB Connection Failed" + err))
app.use(session({
secret: 'random secret',
resave: false,
saveUninitialized: false,
// store: MongoStore.create({ mongoUrl: process.env.ATLAS_URI }),
cookie: {
expires: 7 * 24 * 6 * 60 * 1000,
secure: false,
},
}));
app.use(cookieParser())
app.use(passport.initialize())
app.use(passport.session())
app.use("/auth", auth)
I know a cookie is being created when i authenticate a user because if i uncomment out the store in app.use(session({...}) i see session IDs and cookies in my mongodb. But how can I send it to the browser?

try this config for the session options.
my version of express-session is "^1.17.2"
app.use(session({
name: 'random name',
resave: false,
saveUninitialized: false,
secret: 'random secret',
store: MongoStore.create({
mongoUrl: config.DatabaseUrl,
ttl: 14 * 24 * 60 * 60 // = 14 days. Default
})
}));
if this config does not work, check your passport authenticate function that set session true like the below example :
passport.authenticate('local.register', {session: true}, (err, user): void => {
// When res has an Error
if (err) return res.redirect('/auth/register');
return res.redirect('/');
})(req, res);

Related

trying to connect to Redis using typescript and nodejs

I am trying to connect to Redis using typescript and nodejs but I keep getting **
error TS2693: 'RedisStore' only refers to a type, but is being used as a value here.**
let redisCLient = createClient({legacyMode: true});
redisCLient.connect().catch(console.error);
declare module "express-session" {
interface SessionData {
isLoggedIn: boolean;
}
}
// middleware
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(cors());
app.use(
session({
secret: "reddit_apples_should_be_next",
resave: false,
saveUninitialized: false,
store: new RedisStore({client: redisCLient}),
})
);
You can do stuff like this
Basic Redis setup
Import statements
const express = require('express');
const session = required('express-session');
const redis = require('redis');
const connectRedis = require('connect-redis');
const app = express();
app.use(express.json());
connection
const RedisStore = connectRedis(session);
const redisClient = redis.createClient(
port: 6379,
host: 'localhost'
});
configure session middleware
app.use(session({
store: new RedisStore({client: redisClient}),
secret: 'mySecret',
saveUninitialized: false,
resave: false,
name:'sessionId',
cookie: {
//secure false for non https request , keep false in production
secure: false,
// if true, prevents client side JS from reading the cookie
httpOnly: true,
//session age in millisec // 30 mins
maxAge: 1000 * 60 * 30
}
}));

MongoStore, Atlasdb return the mongoUrl and ClientPromise

I am getting error while trying to save session on mongodb. Here is my code.
//MIDDLEWARE FUNC
app.use(methodOverride('_method',{methods: ['POST','GET']}))
app.use(Express.static(path.join(__dirname, 'public')))
app.use(Express.urlencoded({extended:true}))
app.use(Express.json())
app.use(session({
secret: 'my_keyboard_cat',
resave: false,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: process.env.DB_URI,
dbName: 'sessions'
})
}))
app.use(flash())
app.use((req,res,next) => {
res.locals.flashMessages = req.flash()
next()
})
and error is : Assertion failed: You must provide either mongoUrl|clientPromise|client in options
/app/node_modules/connect-mongo/build/main/lib/MongoStore.js:119
throw new Error('Cannot init client. Please provide correct options')
Error: Cannot init client. Please provide correct options

MERN project | Heroku doesn't set client-side cookie

My MERN project work well on my local but when I deployed it I get 401 error while fetching user. Heroku doesn't set client-side cookie. Then I have searched on google first ı change my cookie-session to express-session and some other configuration and still, it doesn't work on Heroku.
https://github.com/olcaykaplan/passport_google
cors:
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
allowedHeaders: ['Content-Type', 'Authorization']
})
);
express session:
app.use(
express.session({
secret: "secret",
resave: false,
saveUninitialized: true,
store: sessionStore,
proxy: true,
cookie: {
httpOnly:true,
secure: true,
maxAge: oneDay,
},
})
);
if your client side work on local,
change secure value to false, remove proxy and sameSite
The project was working fine with the following cors and session information
app.use(
cors({
origin: "netlify url",
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
allowedHeaders: ['Content-Type', 'Authorization']
})
);
const oneDay = 1000 * 60 * 60 * 24; // Equals 1 day (1 day * 24 hr/1 day * 60 min/1 hr * 60 sec/1 min * 1000 ms / 1 sec)
app.use(cookieParser("secret"));
app.use(
express.session({
secret: "secret",
resave: false,
saveUninitialized: true,
store: sessionStore,
proxy: true,
cookie: {
sameSite:"none",
//path: "/",
httpOnly:true,
secure: true,
maxAge: oneDay,
},
})
);

session is getting expired after closing browser in express.js

I used both cookie-session and express-session, I also specified maxAge but still, it's no use.
const expressSession = require("cookie-session");
const IN_PROD = process.env.NODE_ENV === "production";
app.use(
expressSession({
name: process.env.SESSION_NAME, //setting custom name
resave: false, // do not store if it never modified
secret: process.env.SESSION_SECRETE, // secrete key which we dont't want expose to client
saveUninitialized: false, //dont save the session which is empty
cookie: {
maxAge: 30 * 24 * 60 * 60 * 1000, //Session liftime
sameSite: true,
secure: IN_PROD, //set true when application is in production mode and false when it is in development mode
},
})
);

express session is not working with vuejs and axios

Session initialize in express.js also used passport.js for local-authentication which is working fine. But the session/cookie is not working
app.use(serveStatic(__dirname + '../../dist'));
mongoose.connect(config.database, function(err){
if(err) console.log(err);
console.log('Connected to DB');
})
app.use(cors({
origin:['http://localhost:8080'],
credentials: true // enable set cookie
}));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.urlencoded({ 'extended': 'false' }));
// required for passport
require('./config/passport')(passport); // pass passport for configuration
app.use(session({
secret: config.secret,
resave: true,
saveUninitialized: true,
cookie: { secure: true }
}));
// session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
Get request with axios is below
axios.get(this.url + '/user', {withCredentials: true})
.then(response => {
console.log(response);
})
.catch(e => {
this.errors.push(e)
})
Refer tutorial to store sessions or cookies using passport.js and express.js
app.use(session({
secret: config.secret,
resave: true,
saveUninitialized: true,
cookie: { secure: true }
}));
instead of this try:
app.use(express.session({
secret: config.secret,
resave: true,
saveUninitialized: true,
cookie: { secure: true }
}));
app.use(passport.session());

Resources