Passport-Local 无法验证 Express Session cookie

Passport-Local fails to auth Express Session cookie

在调用未受保护的路由时,我能够打印并响应 req.cookies

处的值
{
    "cookies": {
        "connect.sid": "s:PqWvDsoKLMeCyRd8pGN<removed>",
        "testCookie": "testValue"
    },
    "signedCookies": {}
}

然而这条路线returns401 Unauthorized

router.get('/authCheck', passportWithLocalStrategy.authenticate('local'), (req: Request, res: Response, next: NextFunction) => {
  res.status(204).send();
});

有谁知道可能导致会话 cookie 无法验证的原因?

这是我的主要 server.ts 文件,de/serialization 和中间件堆栈:

// 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( 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>

我已经设置了我的 Passport LocalStrategy,如下所示:

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;

以上导出作为 passportWithLocalStrategy 引入路由器文件(对于 /authCheck 处的路由)。如果我只是将 passport 从库文件夹导入到该文件,路由就会中断,无限期挂起。

更新

我尝试取消保护路由并访问 req.isAuthenticated()。它总是 returns false 即使会话 cookie 存在。

我在登录时看到了这条信息req.session

Session Session {
  cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true }  

你应该有一个单独的登录路由调用 passport.authenticate 之后 returns 成功 passport 将添加 req.session.passport 值和序列化的 userId。您只需在登录用户时执行此过程一次。

然后 /authCheck 路由可以用只检查用户是否仍然登录的中间件重构。

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