Reputation: 4292
On a call to an unprotected route I am able to print and respond with the values at req.cookies
{
"cookies": {
"connect.sid": "s:PqWvDsoKLMeCyRd8pGN<removed>",
"testCookie": "testValue"
},
"signedCookies": {}
}
However this route returns 401 Unauthorized
router.get('/authCheck', passportWithLocalStrategy.authenticate('local'), (req: Request, res: Response, next: NextFunction) => {
res.status(204).send();
});
Does anyone know what could be causing the session cookie not to authenticate?
Here is my main server.ts file, de/serialization, and the middleware stack:
// called to set a cookie initially
passport.serializeUser((user: any, callback) => {
callback(null, user.id as string);
});
// called every time a request is made
passport.deserializeUser(async (userId: string, callback) => {
const pgClient = new PgClient();
try {
pgClient.connect();
const userRecord = (await pgClient.query('SELECT * FROM app_user WHERE CAST(id as text) = CAST($1 as text)', [userId])).rows[0];
pgClient.end();
callback(null, userRecord);
} catch (error) {
callback(error);
}
});
server
.use(cors())
.use(express.json())
.use(expressSession({ secret: process.env.SESSION_SECRET! }))
.use(cookieParser())
.use(passport.initialize())
.use(passport.session())
.use(rootRouter)
<other routers removed>
I have setup my Passport LocalStrategy as shown:
async function useDatabaseToVerifyUserAndPassword(localUserName: string,
localPassword: string, doneCallback: any) {
const pgClient = new PgClient();
try {
await pgClient.connect();
const queryResult = await pgClient.query(selectUserQuery, [localUserName]);
pgClient.end();
const userData: UserMatch = queryResult.rows[0];
if (typeof userData === 'undefined' || typeof userData.password_hash === 'undefined') {
return doneCallback(null, false);
}
const hashesMatch: boolean = await bcrypt.compare(localPassword, userData.password_hash);
if (hashesMatch) {
return doneCallback(null, userData);
}
return doneCallback(null, false); // username not found or passHash mismatch. Prints 401 UnAuth
} catch (error) {
return doneCallback(error, false);
}
}
const strategyOptions = {
usernameField: 'localUserName',
passwordField: 'localPassword',
};
const localStrategy = new LocalStrategy(strategyOptions, useDatabaseToVerifyUserAndPassword);
passport.use(localStrategy);
export default passport;
The above export is brought into the router file (for the route at /authCheck
) as passportWithLocalStrategy
. If I just import passport
from the library folder to that file, the route breaks, hanging indefinitely.
Update
I have tried unprotecting the route and accessing req.isAuthenticated()
. It always returns false even when the session cookie is there.
I see this information printed when logging req.session
Session Session {
cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true }
Upvotes: 1
Views: 75
Reputation: 2028
You should have a separate login route that calls passport.authenticate
after that returns successfully passport will add req.session.passport
value with the serialized userId. You only need to do this process once when logging in a user.
The /authCheck
route can then be refactored with middleware that just checks that the user is still logged in.
router.get('/authCheck', (req: Request, res: Response, next: NextFunction) => {
// passport isAuthenticated method
if(req.isAuthenticated()){
//req.isAuthenticated() will return true if user is logged in
return res.status(204).send();
} else{
res.redirect("/login");
}
});
Upvotes: 1