我创建了mern stack react应用程序,使用express和nodejs作为后端服务。我正在尝试为我的应用程序创建一个登录系统,使用cookie中的jwt作为凭据。我正在使用axios,在前端,为我的调用创建端点。也使用redux工具包来管理一切。我成功地进行了注册,但登录时遇到了问题。当我尝试将我创建的某个用户连接到应用程序并获取Cookie和令牌时,我的控制台中出现以下错误:响应中的“Access-Control-Allow-Credentials”标头的值为“”,当请求的凭据模式为“包含”时,该值必须为“true”。我在这个特定错误上停留了很长一段时间,但没有解决方案。如果有人能提供帮助,我将非常感谢。
我的api组件在前面:
const baseURL="http://localhost:8000";
axios.defaults.withCredentials=true;
const API=axios.create({
baseURL,
});
export const signIn=(formData)=>API.post('/authentication/signin',formData);
export const login=(formData)=>API.post('/authentication/login',formData);
我的api调用使用redux形式转换在我的切片内:
export const signup=createAsyncThunk('auth/signup',async({formData},{fulfillWithValue,rejectWithValue})=>{
try{
const response=await api.login(formData);
console.log(response.token);
return fulfillWithValue(response.token);
}catch(err){
rejectWithValue(err.response.data)
}
})
我的后端cors设置:
app.use(cors())
也是我的后端登录函数:
export const signUser=catchAsync(async(req,res,next)=>{
const email=req.body.email;
const password=req.body.password;
if(!email||!password){
return next(new ErrorHandling('You did not entered user name or password',404));
}
const user=await User.findOne({email}).select('+password');
if(!user||!(await user.correctPassword(password,user.password))){
return next(new ErrorHandling('User name or password are incorrect',400));
}
const token=jsonwebtoken.sign({id},process.env.JWT_SECRET,{
expiresIn:process.env.JWT_EXPIRES_IN} );
const cookieOptions={
onlyHttp:true
}
if(process.env.NODE_ENV=='production'){
cookieOptions.secure=true;
cookieOptions.expires=new Date(Date.now()+1000*60) //Will expires within an hour
}
res.cookie('jwt',token,cookieOptions);
return res.status(statusCode).json({
status:"success",
token,
data: user
})
});
我的package.json文件:
{
"name": "y",
"version": "1.0.0",
"description": "Social media blog application",
"main": "index.js",
"type": "module",
"proxy": "http://localhost:3000",
..........
我的后端中的index.js文件:
const app=express();
app.use(express.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(cors())
dotenv.config({path:'./config.env'})
let database=process.env.DATABASE;
const port= process.env.PORT||5000
database=process.env.DATABASE.replace('<password>',process.env.DATABASE_PASSWORD);
app.use('/post',postRoute);
app.use('/user',userRoute);
app.use('/authentication',authRoute);
app.all('*',(req,res,next)=>{
next(new ErrorHandling("Can't find results check if path is valid",404));
})
app.use(ErrorController)
let conn=mongoose.connect(database,{
useNewUrlParser: true,
// useCreateIndex:true,
// useFindAndModify:false,
useUnifiedTopology: true
}).then(data=>{
if(data){
console.log("Successfully connected to server");
}
else{
throw new Error("Unable to connect");
}
}).catch(err=>{
console.log(err.message);
})
app.listen(port,()=>{
console.log(`Listening to port ${port}`);
})
**更新:**非常感谢您的建议,我发现问题是主体解析器没有在正确的位置,所以我把它放在我的后端index.js文件的中间件列表的最后,它工作了
1条答案
按热度按时间wi3ka0sx1#
使用代理!您的请求不应该直接路由到不同(
localhost
/development)端口上的后端!想象一下,如果您想在开发中更改服务器运行的端口号。有多种方法可以做到这一点,但下面是有关这一切的react文档:https://create-react-app.dev/docs/proxying-api-requests-in-development/。
对于您的情况,您的API代码可以更改为:
有了代理,就不需要在头中使用
Access-Control
了,请求应该像客户端和服务器托管在同一个端口上一样通过。https://my-app.com/api/
),那么你永远不必担心代理的开发。如果你同时开发客户端和后端,那么代理成为禁用CORS和其他可能出现的问题的一个很好的替代方案。快乐编码!:)