打字稿无法识别快速会话中的用户类型
Typescript is not recognising the type of user from express-session
我正在从数据库中检索用户对象并将其设置在快速会话中:
export const postLogin = async (
request: Request,
response: Response,
next: NextFunction
): Promise<void> => {
try {
request.session.user = await UserModel.findById('6127bd9d204a47128947a07d').orFail().exec()
response.redirect('/')
} catch (error) {
next(error)
}
}
然后我在用户对象上调用 Mongoose 方法 populate()
以获取与其关联的购物车:
export const getCart = async (
request: Request,
response: Response,
next: NextFunction
): Promise<void> => {
try {
const userWithCartProducts = await request.session.user
.populate('cart.items.productId')
.execPopulate()
} catch (error) {
next(error)
}
}
但是这里我得到一个错误:TypeError: request.session.user.populate is not a function
我已经在 express-session 上定义了自定义用户类型,如下所示:
declare module 'express-session' {
interface SessionData {
user?: DocumentType<User>
}
}
正如您在上面 user
的定义中看到的,我使用 DocumentType<User>
因为我使用 Typegoose 输入我的模型。我不确定这是否是 Typegoose 的处理方式。
我做错了什么?任何输入将不胜感激。
问题是 session
对象中的 user
对象被 MongoDBStore
提取了。 MongoDBStore
不知道 Typegoose 中定义的 User
模型,因此,当它从会话数据库中获取数据时,它只获取原始数据,而不是 Typegoose 模型中定义的方法.
所以,为了解决这个问题,当一个新的请求进来时,在初始化 express-session 之后,在一个中间件中,我们需要从数据库中获取一次用户并放入 request
对象中如下所示:
app.use(initializeUser)
export const initializeUser = async (request: Request, response: Response, next: NextFunction): Promise<void> => {
try {
request.user = await User.findById(request.session.user._id).orFail().exec()
next()
} catch (error) {
next(error)
}
}
对于 Typegoose,在 Request
上定义 User
模型如下:
declare global {
declare namespace Express {
export interface Request {
user?: DocumentType<User>
}
}
}
如问题中所述,在 login
路由中,即使我们将 user
对象存储在 session
中,请求也会在那里终止,会话(以及使用 user
对象)被保存到数据库中。但是下一次 request
进来时, session
中可用的 user
对象被 MongoDBStore
检索,它不知道 User
模型并且Typegoose 定义的方法。所以,这就是我们解决这个问题的方法。同样的解决方案也适用于 Javascript with Mongoose。
我正在从数据库中检索用户对象并将其设置在快速会话中:
export const postLogin = async (
request: Request,
response: Response,
next: NextFunction
): Promise<void> => {
try {
request.session.user = await UserModel.findById('6127bd9d204a47128947a07d').orFail().exec()
response.redirect('/')
} catch (error) {
next(error)
}
}
然后我在用户对象上调用 Mongoose 方法 populate()
以获取与其关联的购物车:
export const getCart = async (
request: Request,
response: Response,
next: NextFunction
): Promise<void> => {
try {
const userWithCartProducts = await request.session.user
.populate('cart.items.productId')
.execPopulate()
} catch (error) {
next(error)
}
}
但是这里我得到一个错误:TypeError: request.session.user.populate is not a function
我已经在 express-session 上定义了自定义用户类型,如下所示:
declare module 'express-session' {
interface SessionData {
user?: DocumentType<User>
}
}
正如您在上面 user
的定义中看到的,我使用 DocumentType<User>
因为我使用 Typegoose 输入我的模型。我不确定这是否是 Typegoose 的处理方式。
我做错了什么?任何输入将不胜感激。
问题是 session
对象中的 user
对象被 MongoDBStore
提取了。 MongoDBStore
不知道 Typegoose 中定义的 User
模型,因此,当它从会话数据库中获取数据时,它只获取原始数据,而不是 Typegoose 模型中定义的方法.
所以,为了解决这个问题,当一个新的请求进来时,在初始化 express-session 之后,在一个中间件中,我们需要从数据库中获取一次用户并放入 request
对象中如下所示:
app.use(initializeUser)
export const initializeUser = async (request: Request, response: Response, next: NextFunction): Promise<void> => {
try {
request.user = await User.findById(request.session.user._id).orFail().exec()
next()
} catch (error) {
next(error)
}
}
对于 Typegoose,在 Request
上定义 User
模型如下:
declare global {
declare namespace Express {
export interface Request {
user?: DocumentType<User>
}
}
}
如问题中所述,在 login
路由中,即使我们将 user
对象存储在 session
中,请求也会在那里终止,会话(以及使用 user
对象)被保存到数据库中。但是下一次 request
进来时, session
中可用的 user
对象被 MongoDBStore
检索,它不知道 User
模型并且Typegoose 定义的方法。所以,这就是我们解决这个问题的方法。同样的解决方案也适用于 Javascript with Mongoose。