redux 由于我的后端中的CORS策略,无法访问cookie

gmxoilav  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(169)

我创建了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文件的中间件列表的最后,它工作了

wi3ka0sx

wi3ka0sx1#

使用代理!您的请求不应该直接路由到不同(localhost/development)端口上的后端!想象一下,如果您想在开发中更改服务器运行的端口号。
有多种方法可以做到这一点,但下面是有关这一切的react文档:https://create-react-app.dev/docs/proxying-api-requests-in-development/
对于您的情况,您的API代码可以更改为:

axios.defaults.withCredentials=true;
const API=axios.create({
    headers:{
        //"Access-Control-Allow-Origin":'*',
        'Content-Type':'application/json'
    }
});
export const signIn=(formData)=>API.post('/authentication/signin',formData);
export const login=(formData)=>API.post('/authentication/login',formData);

有了代理,就不需要在头中使用Access-Control了,请求应该像客户端和服务器托管在同一个端口上一样通过。

  • 关于代理的注意事项:* 如果你有一个实时的服务器,一些可靠的东西会一直在那里(例如https://my-app.com/api/),那么你永远不必担心代理的开发。如果你同时开发客户端和后端,那么代理成为禁用CORS和其他可能出现的问题的一个很好的替代方案。

快乐编码!:)

相关问题