Chrome 获取 Set-cookie 标头但未将其放入新请求中

Posted

技术标签:

【中文标题】Chrome 获取 Set-cookie 标头但未将其放入新请求中【英文标题】:Chrome get Set-cookie header but doesnt put it in a new requests 【发布时间】:2020-12-12 13:18:28 【问题描述】:

我正在开发一个移动应用程序,前端使用 React Native,后端使用 NodeJ。我为这个应用程序设置了一个身份验证机制。后端工作正常。我用邮递员测试过。在使用正确数据登录请求后,服务器会在“Set-cookie”标头中向我发送一个 cookie。然后我把我的下一个请求头作为“cookie”,我得到了我的数据。但是,当我使用 React Native 部分时,它的工作方式有所不同。我现在正在使用 Chrome 浏览器 来测试应用程序,我可以看到浏览器获取了一个带有登录请求响应的 set-cookie 标头,(另外我已经看到服务器与用户创建了一个新的 cookie里面的信息)。但是对于下一个请求(比如它的“/home”),它不会发回 cookie,因此服务器无法识别用户并创建一个新的 cookie(其中没有用户信息)并返回 403 响应。

人们建议您应该采取一些解决方案。我在这里分享这些,但没有一个对我有用。

    在您的请求或 axios 对象中加上 withCredentials: true(没有解决问题) 为服务器中的 cookie 设置 httpOnly:false(没有解决问题) 将 corsOptions 设置为 var corsOptions = origin: '*',credentials: true,exposedHeaders: ["Set-Cookie"]; (还是不行) 我也使用 universal-cookie 库从前端获取 cookie 数据,但也无法获取 cookie 值 在 url 中使用 127.0.0.1 而不是“localhost” 也不起作用(有人说 cookie 在一级域中不起作用)

这是我的 React Native - Axios 代码

const axiosObj = axios.create(
    baseURL:"http://localhost:3000/",
    headers: 
      'Content-Type': 'application/json',
    ,
    responseType: 'json',
    withCredentials: true, 
  );

export function get(url)
    return new Promise(function(resolve,reject)
        axiosObj.get(url).then(res => 
            console.log(res)
            return res.data
        )
    ) 
;

export function post(url,data)
    return new Promise(function(resolve,reject)
        axiosObj.post(url,data).then(res => 
            console.log(res.headers)
            const cookies = new Cookies(res.headers.cookie);
        console.log("document cookie",document.cookie)    
        console.log(cookies.getAll()); 
            resolve(res)
        )
    ) 

这里是相关代码

 var app = express();
app.use(cookieParser('keyboard cat'));


var corsOptions = 
  origin: '*',
  credentials: true,
  exposedHeaders: ["Set-Cookie"]
 ;
app.use(cors(corsOptions))
app.use(logger('dev'));
app.use(express.json());
app.use(bodyParser.urlencoded( extended: false )); 
app.use(express.urlencoded( extended: false ));
app.use(express.static(path.join(__dirname, 'public')));

//session settings
app.use(session(
  genid: (req) => 
    console.log('Inside the session middleware')
    console.log(req.sessionID)
    return uuidv4(); // use UUIDs for session IDs
  ,
  store: new FileStore(),
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie:  httpOnly: false,
    expires: new Date(Date.now() + (30 * 86400 * 1000))
))

这是我登录后在服务器上的会话文件

"cookie":"originalMaxAge":2591995208,"expires":"2020-09-22T20:22:56.993Z","httpOnly":false,"path":"/","passport":"user":"_id":"5f307fc99f5c667918a56122","username":"test","__v":0,"__lastAccess":1598214181785

这可能是什么问题?有什么想法吗?

编辑: 我从前端 (JS) 了解到 没有达到“Set-cookie”是正常的。 (虽然在一些网站上,它说你可以把 httpOnly: false 放在 cookie 设置中,它可以解决这个问题)。 因此,如果我没有到达前端代码中的标头,实际上并不重要。我的响应标头中有“set-cookie”标头,并且 chrome 无法识别 cookie 并将其放入 f12 的 cookies 部分(也没有在 req.header 中设置它)。这里有问题

编辑 2:我对我的问题有一些想法。

由于我正在使用 React Native 并且它不应该在 Chrome 浏览器中工作,它可能会以某种方式导致浏览器没有设置 cookie。我将创建一个反应项目并尝试从那里访问 cookie。 => 我解决了与该问题无关的问题。虽然我在使用 react 应用程序进行测试时解决了问题

我的 react-native 代码出现“service-worker.js”错误。看起来它不会影响代码的功能,但它可能会以某种方式影响这种 cookie 情况 => 解决问题后我仍然收到此错误,因此与此无关。

我还尝试了一个用于 cookie 的 react native 应用程序 (react-native-cookie),但它的代码仅适用于 android 或 ios,因此不适用于浏览器。

【问题讨论】:

浏览器阻止前端 javascript 代码访问 Set-Cookie 标头。 Fetch 规范要求浏览器阻止前端代码访问它; Fetch 规范要求阻塞。请参阅fetch.spec.whatwg.org/#forbidden-response-header-name,其中 Set-Cookie 定义为 禁止的响应标头名称,必须从任何暴露给前端代码的响应中过滤掉。另见developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie 我刚刚通过“set-cookie”标头做了一些研究,看起来设置 httpOnly:false 应该可以解决 Js(前端)的访问问题 并且 cookie 是使用 set-cookie 标头设置的(没有看到我可以使用的任何其他标头)。所以一定是用js搭配set-cookie的一种方式。虽然如果一切正常,我不必接触那个 cookie。 Chrome 应该自动将其设置为响应。在我的情况下它不是。这就是问题 【参考方案1】:

我解决了我的问题。看起来我的代码有两个问题。第一个是在具有 cors 设置的服务器中。第一个版本是这样的:

var cors = require('cors');
var corsOptions = 
  origin: '*',
  credentials: true,
  exposedHeaders: ["set-cookie"]
 ;
app.use(cors(corsOptions))

所以基本上我使用 cors 模块进行设置。当我为测试创建一个 React 应用程序时,我收到了一个 cors 错误(来源错误)。不知何故,我的 cors 设置不适用于图书馆。所以我用下面的代码改变了这段代码。

app.use(function (req, res, next) 
     // Website you wish to allow to connect
     res.setHeader('Access-Control-Allow-Origin', '*');
     // Request methods you wish to allow
     res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
     // Request headers you wish to allow
     res.setHeader('Access-Control-Allow-Headers', 'Origin,X-Requested-With,content-type,set-cookie');
     // Set to true if you need the website to include cookies in the requests sent
     // to the API (e.g. in case you use sessions)
     res.setHeader('Access-Control-Allow-Credentials', true);
  
     // Pass to next layer of middleware
     next();
   );

我仍然有一些 cors 错误。您可能会收到 cors 错误的另一个原因是 chromes 同源策略。我使用的是 Windows 10,所以我打开了下面的搜索栏并粘贴到那里

 chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security

新的 chrome 浏览器在没有网络安全策略的情况下打开。然后我的反应应用程序运行良好。我可以使用 document.cookie 访问 cookie,也在 f12 下的应用程序选项卡 >> cookie 中,我可以看到我的 cookie。所以谷歌浏览器保存了我的cookie。在同一个 chrome 窗口中,我运行我的 react native 应用程序,它也成功运行。所以我认为这只是因为 chrome 的安全策略并更改了我的 cors 设置,我又开始收到错误。

总之,我必须改变两件事。

    Cors 模块不起作用,我手动设置了标题,它们工作正常。 我不得不禁用 Chrome 的同源策略

【讨论】:

我遇到了同样的问题,但使用带有默认选项的 cors 对我有用。不确定在禁用安全性的情况下运行是否可行。部署后有遇到 cookie 相关的问题吗?

以上是关于Chrome 获取 Set-cookie 标头但未将其放入新请求中的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Chrome 会忽略 Set-Cookie 标头?

在 chrome 中显示时没有 Set-Cookie 标头

Set-Cookie 标头未出现在 Google Chrome 中

这个Set-Cookie标头出了什么问题?

在响应标头中使用 apollo,cookie 但未设置

为啥我看到多个 set-cookie 标头?