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 标头但未将其放入新请求中的主要内容,如果未能解决你的问题,请参考以下文章