【发布时间】: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 应该自动将其设置为响应。在我的情况下它不是。这就是问题
标签: node.js react-native google-chrome cookies cors