React+GraphQL应用中Cannot read properties of undefined (reading 'isAuth')报错求助
解决React+GraphQL创建帖子时"Cannot read properties of undefined (reading 'isAuth')"错误
错误信息
{ "errors": [ { "message": "Cannot read properties of undefined (reading 'isAuth')", "status": 500 } ], "data": { "createPost": null } }
问题原因
- 中间件顺序错误:你把GraphQL端点配置放在了认证中间件之前,导致GraphQL请求不会经过认证中间件处理,
req.isAuth自然不会被设置。 - GraphQL上下文未传递Express请求对象:
graphql-http的createHandler默认不会将Express的req对象传递给resolver,导致resolver里的req参数不是经过认证中间件处理后的请求对象。
解决方案
1. 修正中间件挂载顺序
将认证中间件移到GraphQL端点配置之前,确保所有请求先经过认证处理:
// 先挂载认证中间件 app.use((req, res, next) => { console.log("Auth middleware executed"); const authHeader = req.get("Authorization"); if (!authHeader) { req.isAuth = false; return next(); } console.log(authHeader); const token = authHeader.split(" ")[1]; let decodedToken; try { decodedToken = jwt.verify(token, SECRET_KEY); } catch (error) { req.isAuth = false; return next(); } if (!decodedToken) { req.isAuth = false; return next(); } req.userId = decodedToken.userId; req.isAuth = true; next(); }); // 再挂载GraphQL端点 app.use('/graphql', createHandler({ schema: graphqlSchema, rootValue: graphqlResolver, // 添加context配置,传递Express的req对象 context: async ({ req }) => ({ req: req.raw }) }));
2. 调整Resolver获取请求对象
修改createPost resolver,从context中获取经过处理的Express请求对象:
const createPost = async ({ postInput }, context) => { const req = context.req; // 从context中取出req console.log(req); if (!req.isAuth) { const error = new Error("Not Authenticated"); error.code = 401; throw error; } // 剩余代码保持不变 const errors = []; if ( validator.isEmpty(postInput.title) || !validator.isLength(postInput.title, { min: 5 }) ) { errors.push("Title is invalid"); } if ( validator.isEmpty(postInput.content) || !validator.isLength(postInput.content, { min: 5 }) ) { errors.push("Content is invalid"); } if (errors.length > 0) { const error = new Error("Invalid Input"); error.data = errors; error.code = 422; throw error; } const user = await User.findById(req.userId); if (!user) { const error = new Error("Invalid User"); error.code = 401; throw error; } const post = new Post({ title: postInput.title, content: postInput.content, imageUrl: postInput.imageUrl, creator: user, }); const createdPost = await post.save(); user.posts.push(createdPost); console.log('Done Succesfully'); return { ...createdPost._doc, _id: createdPost._id.toString(), createsAt: createdPost.createdAt.toISOString(), updatedAt: createdPost.updatedAt.toISOString(), }; };
验证步骤
- 重启后端服务,确保中间件顺序和context配置生效。
- 再次发起创建帖子的mutation,检查
req.isAuth是否能正确获取到值。 - 确认认证中间件的
console.log输出,验证请求是否经过了认证处理。
内容的提问来源于stack exchange,提问作者Shivam Sharma
相关产品推荐
相关产品推荐

