【问题标题】:How to set cookies express, react.js如何设置cookies express、react.js
【发布时间】:2019-05-22 16:59:26
【问题描述】:

我正在为 node.js 和 react.js 使用 express 构建登录系统。在我的后端,当用户登录时,它会创建一个 cookie。当我转到网络 > 登录时,我可以看到:

设置 Cookie:user_id=s%3A1.E%2FWVGXrIgyXaM4crLOoxO%2Fur0tdjeN6ldABcYOgpOPk;路径=/;仅http;安全

但是当我转到应用程序 > Cookies > http://localhost:3000 时,那里什么也没有。我相信这是因为当我从客户端发出发布请求时,我不允许凭据正确通过。我该怎么做?请告诉我是否可以通过任何方式改进我的问题。

            //Login back-end
            router.post('/login', (req, res, next) => {
                if(validUser(req.body)) {
                    User
                        .getOneByEmail(req.body.email)
                        .then(user => {
                            if(user) {
                                bcrypt
                                    .compare(req.body.password_digest, user.password_digest)
                                    .then((result) => {
                                        if(result) {
                                            const isSecure = process.env.NODE_ENV != 'development';

                                            res.cookie('user_id', user.id, {
                                                httpOnly: true,
                                                secure: isSecure,
                                                signed: true
                                            })
                                            res.json({
                                                message: 'Logged in'
                                            });
                                        } else {
                                            next(new Error('Invalid Login'))
                                        }
                                    });
                            } else {
                                next(new Error('Invalid Login'))
                            }
                        });
                } else {
                    next(new Error('Invalid Login'))
                }
            });

            //Allow CORS index.js
            app.use(
            cors({
                origin: "http://localhost:3000",
                credentials: true
            })
            );

            //Login client side (React.js)
            loginUser(e, loginEmail, password) {
            e.preventDefault();

            let email = loginEmail;
            let password_digest = password;
            let body = JSON.stringify({ email, password_digest });

            fetch("http://localhost:5656/api/login", {
                method: "POST",
                headers: {
                "Content-Type": "application/json"
                },
                credentials: "include",
                body
            })
                .then(response => response.json())
                .then(user => {
                console.log(user);
                });
            }

【问题讨论】:

  • 使用 react-cookie 库,然后可以使用 cookies.get('key' ) 和 cookies.set('key', 'value')
  • 感谢您对萨米尔的评论。但是,我无法让它工作。我正在使用这样的通用 cookie:从 'universal-cookie' 导入 Cookie; const cookies = new Cookies(); cookies.set('myCat', 'Pacman', { path: '/' }); console.log(cookies.get('myCat')); // Pacman 当我转到 Application > Cookies > localhost:3000 时,我可以在那里看到这个 'myCat' cookie。但我不确定如何将它与我的应用程序集成。 (我正在尝试正确显示代码,但我不能。)
  • 您的所有配置似乎都是正确的,除了一件我不确定的事情。当您在登录后路由中设置 cookie 时,请确保 secure 标志为 false(仅用于开发)。在生产中,将其设置为 true。这是因为 localhost 是 HTTP 而不是 HTTPS。因此,请确保您的 isSecure 变量为 false。这是唯一对我来说似乎是潜在问题的事情。

标签: node.js reactjs express


【解决方案1】:

您应该确保在服务器和应用程序中设置“凭据”。

尝试在你的 index.js 或 app.js 服务器端设置这个:

  app.use(function(req, res, next) {
  res.header('Content-Type', 'application/json;charset=UTF-8')
  res.header('Access-Control-Allow-Credentials', true)
  res.header(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept'
  )
  next()
})

并在您的客户端站点中添加如下选项:

let axiosConfig = {
  withCredentials: true,
}

export async function loginUser(data) {
  try {
    const res = await axios.post(
      `${URL}:${PORT}/${API}/signin`,
      data,
      axiosConfig
    )
    return res
  } catch (error) {
    console.log(error)
  }
}

编辑

要在服务器中设置“凭据”,我们需要这一行:

res.header('Access-Control-Allow-Credentials', true)

这将让您处理包含在标头中的凭据。

您还必须告诉axios 在标头中设置凭据:

withCredentials: true

【讨论】:

    【解决方案2】:

    不要忘记调整cors中间件。

    你的 node.js express 代码

    const express = require("express");
    const cors = require('cors')
    
    const app = express();
    
    app.use(cors(
      {
        origin: 'http://localhost:3000',
        optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
      }
    ));
    
    app.use(function(req, res, next) {
      res.header('Content-Type', 'application/json;charset=UTF-8')
      res.header('Access-Control-Allow-Credentials', true)
      res.header(
        'Access-Control-Allow-Headers',
        'Origin, X-Requested-With, Content-Type, Accept'
      )
      next()
    })
    
    app.get("/auth", function(req, res){
    
      res.cookie('token', 'someauthtoken')
      res.json({id: 2});
    });
    
    app.listen(3030);
    

    您的前端代码

    import React, { useEffect } from 'react';
    import axios from 'axios';
    
    
    async function loginUser() {
      try {
        const res = await axios.get(
          'http://localhost:3030/auth',
          {
            withCredentials: true,
          }
        )
        return res
      } catch (error) {
        console.log(error)
      }
    }
    
    function App() {
    
      useEffect(() => {
        loginUser();
      }, [])
    
      return (
        <div>
    
        </div>
      );
    }
    
    export default App;
    

    【讨论】:

      【解决方案3】:

      因为你设置了httpOnly: true

      这将阻止对客户端的可见性,例如从 javaScript document.cookie() 读取。

      你可以通过关闭它来解决这个问题。

      【讨论】:

        【解决方案4】:

        如果您在浏览器中看不到您的 cookie,我认为这是因为您在 cookie 的选项中将 hhtpOnly 设置为 true。

        cookie.httpOnly 指定 HttpOnly Set-Cookie 属性的布尔值。如果为真,则设置 HttpOnly 属性,否则不设置。默认情况下,设置了 HttpOnly 属性。

        注意:将此设置为 true 时要小心,因为兼容的客户端将不允许客户端 JavaScript 看到 document.cookie 中的 cookie

           res.cookie('user_id', user.id, {
                                                    httpOnly: false, // try this
                                                    secure: isSecure,
                                                    signed: true
                                                })

        【讨论】:

          猜你喜欢
          • 2018-08-18
          • 1970-01-01
          • 2023-03-30
          • 2021-02-19
          • 2013-12-26
          • 2022-10-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-12
          相关资源
          最近更新 更多