I am working on a simple Todo web application, and I am stuck in authorisation. I want to protect all my routes by having an active user session.
When doing an API call to a POST route, I keep getting undefined
for req.session.userId
within the checkAuth
middleware. When using the login
route, the session is being set up just fine, but when testing out the addTask
route I get undefined
.
To clarify, I am using Thunder Client in VSCode to do the API calls, and I set up within headers the Cookie option along with the session id.
I have been testing the following route with Thunder Client in VSCode:
router.post('/todos', checkAuth, todoController.addTask);
exports.addTask = (req, res) => {
const {task} = req.body;
const userId = req.session.userId;
const stmt = db.prepare(`INSERT INTO todos (user_id, task) VALUES (?, ?)`);
stmt.run(userId, task, (err) => {
if(err) {
console.error(err.message);
res.status(500).send({error: 'Failed to add task.'});
} else {
res.sendStatus(200);
}
});
stmt.finalize();
};
checkAuth
is a simple custom middleware I have defined in another file and import it:
const checkAuth = (req, res, next) => {
console.log(req.session, req.session.user);
if(!(req.session && req.session.user)) {
return res.status(401).json({error: 'Unauthorized access.'});
}
next();
}
Also the route and controller for the login are the following:
router.post('/login', userController.login);
exports.login = (req, res) => {
const {login, password} = req.body;
db.get(`SELECT * FROM users WHERE email = ? OR username = ?`, [login, login],
(err, user) => {
if(err) {
console.error(err.message);
return res.status(500).json({error: 'Authentication failed. Wrong email or username.'});
}
if(!user) {
return res.status(401).json({error: 'Invalid login or password.'});
}
const passMatch = bcrypt.compareSync(password, user.password);
if(!passMatch) {
res.status(401).json({error: 'Invalid password.'});
}
req.session.user = user;
console.log(user);
res.json({message: 'User authenticated successfully.'})
});
};
And the set up of the session middleware itself:
app.use(
session({
name: 'sid',
secret: process.env.SESSION_KEY,
resave: true,
saveUninitialized: false,
rolling: true,
unset: 'destroy',
proxy: true,
cookie: {
path: '/',
maxAge: 600000, // in ms
httpOnly: false,
secure: false
},
store: new SQLiteStore({db: 'sessions.db', concurrentDB: false})
);