【问题标题】:typescript: req.user is possibly 'undefined' - express and passport js打字稿:req.user 可能是“未定义”-快递和护照 js
【发布时间】:2021-06-11 07:45:27
【问题描述】:

我有一个使用护照工作的 Nodejs 打字稿身份验证系统。

我的问题是,当我在路由中使用req.user 时,我在req.user 上收到此错误:Object is possibly 'undefined'.

这是 Typescript 的正常行为,但我正在使用中间件来保护我想在其中使用 req.user 的路由,这样req.user 不能被取消定义。

这是我扩展 Express.User 类型的地方:

import { users } from "@prisma/client";

declare global {
    namespace Express {
        interface User extends users {}
    }
}

这是我用来保护登录用户路由的中间件:

export function checkIsAuthenticated(req: Request, res: Response, next: NextFunction) {
    if (req.isAuthenticated()) {
        if (!req.user) req.logOut();
        else return next();
    }
    res.status(400).json({
        errors: [{ message: "no user logged in" }],
    });
}

这是获取用户信息的途径:

export function userRoute(req: Request, res: Response) { // defining the route
    res.json({
        id: req.user.id,               // I'm getting the error in these 4 lines
        username: req.user.username,   //
        email: req.user.email,         //
        role: req.user.role,           //
    });
}

router.get("/user", checkIsAuthenticated, userRoute); // using the route

我不想检查用户是否已定义,因为我不想在每条路线上都这样做,这不是一个好习惯。这就是中间件的用途。

我不擅长 Typescript,所以我需要一些帮助来修复它。 谢谢

【问题讨论】:

  • “我不想检查用户是否已定义,因为我不想在每条路线上都这样做,这不是一个好习惯。” 我不会不是说这是不好的做法。例如,如果您在创建这些路由之一时遗漏了身份验证中间件,它会给您一个很好的显式错误。

标签: node.js typescript express passport.js


【解决方案1】:

我不想检查用户是否已定义,因为我不想在每条路线上都这样做,这不是一个好习惯。

我尝试满足该要求的第一个解决方案不起作用,因此我将其删除。我留下了我的第二个解决方案,即:

但是,如果您不小心在您的路线上使用了其中一个处理程序,那么检查用户请求并给自己一个很好的有用错误消息并没有错。忘记放认证了。看起来像这样:

type RequestWithUser = Request & {user: typeOfUserObject};
function assertHasUser(req: Request): asserts req is RequestWithUser {
    if (!( "user" in req)) {
        throw new Error("Request object without user found unexpectedly");
    }
}

然后你的那些路线的处理程序:

export function userRoute(req: Request, res: Response) {
    assertHasUser(req);
    // ...you can use `req.user` here...
});

Playground example

(你并不需要显式的RequestWithUser 类型,你可以使用asserts req is Request & {user: typeOfUserObject}。)

【讨论】:

  • 非常感谢您的帮助!如果 express 可以检测到我正在检查中间件中的请求属性以获取请求,那就太好了,但我认为这是 JS 或 TS 目前的限制,我们现在必须解决它。
【解决方案2】:

export function userRoute(req: Request, res: Response) { // defining the route
    res.json({
        id: req.user!.id,               // you tell typescript that req.user for sure not. null
        username: req.user!.username,   //
        email: req.user!.email,         //
        role: req.user!.role,           //
    });
}

router.get("/user", checkIsAuthenticated, userRoute);

【讨论】:

  • 这可行,但最佳做法是避免此类断言。
猜你喜欢
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 2022-11-13
  • 2022-10-06
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 2014-07-20
相关资源
最近更新 更多