搭建MERN应用遭遇CORS错误:凭证模式include下Origin不可为通配符
解决MERN应用中的CORS凭证模式错误
从源'http://localhost:3000'访问'http://localhost:4000/v2/auth/login'时被CORS策略阻止:预检请求未通过访问控制检查,当请求的凭证模式为'include'时,响应中的'Access-Control-Allow-Origin'头值不能为通配符'*'。
前端登录函数代码
export const login = (email: string, password: string) => async (dispatch: any) => { const header = { 'Content-Type': 'application/json', // 'Access-Control-Allow-Origin': 'http://localhost:4000', 'Access-Control-Allow-Credentials': 'true' } const response = await fetch(LOGIN_API, { method: 'POST', credentials: 'include', headers: header, body: JSON.stringify({email: email, password: password}) }); const json: CommonResponse = await response.json(); console.log(json); if(json.success){ dispatch({ type: LOGIN_SUCCESS, payload: json.data }); } else{ dispatch({ type: LOGIN_FAILURE, payload: json.message }) } }
后端app.ts代码
dotenv.config(); const app = express(); app.use(cors({ origin: "http://localhost:3000", credentials: true, })); app.use(express.json()); app.use(cookieParser()); app.use('/v2/auth', userRoute); app.use('/v1/room', roomRoute); app.use('/v1/messages', messageRoute); app.use(ErrorMiddleware); export default app;
路由及登录函数代码
路由代码
const router = express.Router(); router.route('/login').post(loginWithEmail); router.route('/signup').post(createUser); router.route('/logout').post(authenticateUser, logout); router.route('/me').get(authenticateUser, getUserDetails);
登录处理函数代码
export const loginWithEmail = catchAsyncError( async (req: Request, res: Response, next: NextFunction) => { const { email, password } = req.body; console.log(email, password); const user = await User.findOne({email: email}); if(user === null){ return next(new ErrorHandler("Invalid Credentials", 400)); } const isPasswordHashed: boolean = await bcrypt.compareSync(password, user.password!); if(!isPasswordHashed){ return next(new ErrorHandler("Invalid Credentials", 400)); } const data: UserToken = { user:{ id: user.id } } res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); sendToken(res, data, "Login Successful"); });
问题分析与解决步骤
- 移除前端无效请求头:前端请求中
Access-Control-Allow-Credentials是后端响应头,无需前端发送,直接删除该字段:
const header = { 'Content-Type': 'application/json' // 移除 'Access-Control-Allow-Credentials': 'true' }
删除后端重复响应头设置:全局CORS中间件已经自动处理
Access-Control-Allow-Origin,登录函数中手动添加的该行代码属于冗余操作,可能导致响应头冲突,直接删除res.header('Access-Control-Allow-Origin', 'http://localhost:3000')。验证预检请求响应:打开浏览器开发者工具网络面板,查看OPTIONS预检请求的响应头,确认:
Access-Control-Allow-Origin值为http://localhost:3000而非*Access-Control-Allow-Credentials值为trueAccess-Control-Allow-Methods包含POST
完成以上操作后重启前后端服务,即可解决该CORS错误。
内容的提问来源于stack exchange,提问作者Brahm Bind Singh
相关产品推荐
相关产品推荐

