typescript - 打字稿无法识别快速会话中的用户类型
问题描述
我正在从数据库中检索用户对象并将其设置在快速会话中:
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 的做法。
我究竟做错了什么?任何输入将不胜感激。
解决方案
问题是user
对象中的session
对象是由MongoDBStore
. MongoDBStore
不知道 Typegoose 中定义的模型User
,因此,当它从会话数据库中获取数据时,它只获取原始数据,而不是 Typegoose 模型中定义的方法。
所以,为了解决这个问题,当一个新的请求进来时,在初始化快速会话之后,在中间件中,我们需要从数据库中获取一次用户并放入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,定义User
模型Request
如下:
declare global {
declare namespace Express {
export interface Request {
user?: DocumentType<User>
}
}
}
如问题中所述,在login
路由中,即使我们将user
对象存储在 中session
,请求也会在那里终止,并且会话(连同user
对象)被保存到数据库中。但是下一次request
进来时,不知道模型和Typegoose定义的方法的人会检索到user
可用的对象。所以,这就是我们解决这个问题的方法。同样的解决方案也适用于带有 Mongoose 的 Javascript。session
MongoDBStore
User
推荐阅读
- asp.net-core - 如何在 razor 页面中获取相关数据。EF 核心 5.0
- r - 按单独的列排序 ggplot
- qt - 将地图从 OSM 移植到 QML QT 中的 3D 地图
- javascript - JavaScript:超类中的“this”指的是子类
- node.js - npx create-react-app 不工作,而是抛出错误
- elasticsearch - Kibana:stracktrace 的搜索模式未检索到结果
- reactjs - 读取芯片中的文本
- python - Python - __init__ 参数
- angular - 如何禁用 tslint 文件中的规则“TS2322:类型 'WebSocketAction' 不可分配给类型 'boolean'。”
- flutter - 为什么我的 Intellij Idea Flutter 重命名文件或文件夹重构不起作用?