【问题标题】:fetch: cookies not receiving cookiesfetch: cookie 没有接收到 cookie
【发布时间】:2021-03-03 20:17:09
【问题描述】:

我有一个在 localhost:5000 上运行的快速服务器和在端口 3000 上运行的客户端。 从客户端发送 post 请求以使用 fetch API 登录后,浏览器未设置 cookie。我在响应标头中将 cookie 设置为“set-cookie”,但它没有在客户端的浏览器中设置。

这是我的获取请求代码:

return (
    fetch(baseUrl + "users/login", {
      method: "POST",
      body: JSON.stringify(User),
      headers: {
        "Content-Type": "application/json",
      },
      credentials: "same-origin",
    })

服务器端代码:

router
  .route("/login")
  .options(cors.corsWithOptions, (req, res) => {
    res.sendStatus(200);
  })
  .post(cors.corsWithOptions, (req, res, next) => {
    passport.authenticate("local", (err, user, info) => {
      if (err) return next(err);

      if (!user) {
        res.statusCode = 401;
        res.setHeader("Content-Type", "application/json");
        res.json({ success: false, status: "Log In unsuccessful", err: info });
      }
      req.logIn(user, (err) => {
        if (err) {
          res.statusCode = 401;
          res.setHeader("Content-Type", "application/json");
          // res.header("Access-Control-Allow-Credentials", true);
          res.json({
            success: false,
            status: "Login Unsuccessful!",
            err: "Could not log in user!",
          });
        }

        var token = authenticate.getToken({ _id: req.user._id });
        res.cookie("jwt-token", token, {
          signed: true,
          path: "/",
          httpOnly: true,
          
        });
        res.statusCode = 200;
        res.setHeader("Content-Type", "application/json");

        res.json({ success: true, status: "Login Successful!", token: token });
      });
    })(req, res, next);
  });
  

【问题讨论】:

  • 如果您在 Stack Overflow 上需要帮助,请不要发送您的代码图片你的问题
  • 我已经改了。请立即提供帮助
  • 哦,好吧,我在这里看到您正在尝试使用服务器端会话 cookie 我将给出解决方案,我将给出 express-sessionmongoDb...但是从您的代码中我看到您正在发送许多有效负载数据,但您也应该只在 cors 设置中发送 token only你需要一些配置设置,你会在我的回答中看到

标签: node.js cookies fetch cross-domain


【解决方案1】:

如何使用 Express-session 处理服务器端会话

首先你需要以下包

npm i express-session connect-mongodb-session 或 yarn add express-session connect-mongodb-session

现在我们已经有了设置 mongoStore 和 express-session 中间件所需的包:

//Code in server.js/index.js (Depending on your server entry point)
import expressSession from "express-session";
import MongoDBStore from "connect-mongodb-session";
import cors from "cors";
const mongoStore = MongoDBStore(expressSession);

const store = new mongoStore({
  collection: "userSessions",
  uri: process.env.mongoURI,
  expires: 1000,
});
app.use(
  expressSession({
    name: "SESS_NAME",
    secret: "SESS_SECRET",
    store: store,
    saveUninitialized: false,
    resave: false,
    cookie: {
      sameSite: false,
      secure: process.env.NODE_ENV === "production",
      maxAge: 1000,
      httpOnly: true,
    },
  })
);

现在会话中间件已准备就绪,但现在您必须设置 cors 以接受您的 ReactApp,以便传递 cookie 并由服务器将其设置在那里

//Still you index.js/server.js (Server entry point)

app.use(
  cors({
    origin: "http://localhost:3000",
    methods: ["POST", "PUT", "GET", "OPTIONS", "HEAD"],
    credentials: true,
  })
);

现在我们的中间件都设置好了,让我们看看你的登录路径

router.post('/api/login', (req, res)=>{
    //Do all your logic and now below is how you would send down the cooki

    //Note that "user" is the retrieved user when you were validating in logic
    // So now you want to add user info to cookie so to validate in future
    const sessionUser = {
       id: user._id,
       username: user.username,
       email: user.email,
    };
    //Saving the info req session and this will automatically save in your     mongoDB as configured up in sever.js(Server entry point)
    request.session.user = sessionUser;

    //Now we send down the session cookie to client
    response.send(request.session.sessionID);

})

现在我们的服务器已准备就绪,但现在我们必须修复在客户端发出请求的方式,以便此流程可以 100% 工作:

以下代码:React 应用程序/您在处理登录时使用的任何前端

//So you will have all your form logic and validation and below
//You will have a function that will send request to server 

const login = () => {
    const data = new FormData();
    data.append("username", username);
    data.append("password", password);

    axios.post("http://localhost:5000/api/user-login", data, {
      withCredentials: true, // Now this is was the missing piece in the client side 
    });
};

现在有了所有这些,您现在拥有作为 httpOnly 的服务器会话 cookie

【讨论】:

  • 这是实现服务器端会话的详细信息,希望答案对您的项目和未来项目有所帮助
猜你喜欢
  • 2021-07-03
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
  • 2018-12-20
  • 2014-11-15
相关资源
最近更新 更多