节点获取的会话cookie无效



我现在正在编写一个javascript程序(用于github操作(,但遇到了一个问题
我试图登录www.overleaf.com并访问该页面https://www.overleaf.com/project通过向发送POST请求生成会话cookie之后https://www.overleaf.com/login用我的证书和csrf令牌
但是,当我尝试访问https://www.overleaf.com/project通过GET,我被重定向回https://www.overleaf.com/login
复制保存在浏览器中的会话cookie时,请求的工作方式与预期的一样好。

我试着在命令行中用cURL做同样的事情,结果成功了。

我很确定我的身份验证请求已被Overleaf的服务器接受,因为我曾故意错误地发送密码或csrf令牌,在这两种情况下,响应都不会给我新的会话cookie,而是发送旧的会话cookie。

如果有人知道出了什么问题,我将非常感谢你的意见。

这就是终端中的工作原理,我正试图用nodefetch:
curl -v --header "Content-Type: application/json" --cookie "GCLB=someothercookie;overleaf_session2=firstsessioncookie" --data '{"_csrf":"the_csrf_token", "email": "MYEMAIL", "password":"MYPASSWORD"}' https://www.overleaf.com/login
在javascript中复制它,以获取cookie和csrf令牌,并将
curl -v https://www.overleaf.com/project --cookie "overleaf_session2=returnedsessioncookie; GCLB=someothercookie"作为返回我的项目的html页面的请求。

这是我的javascript代码,我已经检查了两次、三次、四次,但我想我遗漏了一些东西。

const fetch = require("node-fetch");
const parser = require("node-html-parser");
const scparser = require("set-cookie-parser");

async function run() {

const email = process.env.EMAIL;
const password = process.env.PASSWORD;

var cookies = await login(email, password);

console.log(await all_projects(cookies));

}

async function login(email, password) {
const login_get = await fetch("https://www.overleaf.com/login");

const get_cookies = login_get.headers.raw()["set-cookie"];
const parsed_get_cookies = scparser.parse(get_cookies, {
decodeValues: false
});
const overleaf_session2_get = parsed_get_cookies.find(
(element) => element.name == "overleaf_session2"
).value;
const gclb = parsed_get_cookies.find(
(element) => element.name == "GCLB"
).value;
console.log("overleaf_session2_get:", overleaf_session2_get, "gclb:", gclb);

const get_responsetext = await login_get.text();
const _csrf = parser
.parse(get_responsetext)
.querySelector("input[name=_csrf]")
.getAttribute("value");

login_json = { _csrf: _csrf, email: email, password: password };
console.log(login_json);
const login_post = await fetch("https://www.overleaf.com/login", {
method: "post",
body: JSON.stringify(login_json),
headers: {
"Content-Type": "application/json",
"Cookie": "GCLB=" + gclb + ";overleaf_session2=" + overleaf_session2_get
}
});

const post_cookies = login_post.headers.raw()["set-cookie"];
const parsed_post_cookies = scparser.parse(post_cookies, {
decodeValues: false
});
const overleaf_session2_post = parsed_post_cookies.find(
(element) => element.name == "overleaf_session2"
).value;

console.log(
"successful:",
overleaf_session2_get != overleaf_session2_post ? "true" : "false"
);
console.log(await fetch("https://www.overleaf.com/project", {
headers: {
"Cookie": "overleaf_session2=" + overleaf_session2_post
}
}))
return "overleaf_session2=" + overleaf_session2_post;
}

async function all_projects(cookies) {
const res = await fetch("https://www.overleaf.com/project", {
headers: {
Cookie: cookies
}
});
return res;
}

run();

是的,您的身份验证请求可能有效,但这可能是一个安全问题,浏览器不允许您做这样的事情并自由访问另一个网站的cookie。

浏览器不允许您访问其他域的cookie,如果他们这样做了,那么网络将是一个不安全的地方,因为例如Stackoverflow可以访问我的Facebook帐户cookie并提取我的个人信息。

我通过不使用node-fetch并切换到https来解决问题。

以下是行之有效的方法:

async function login(email, password) {
//GET login page
const get = await get_login();
//get necessary info from response
const csrf = parser
.parse(get.html)
.querySelector(`meta[name="ol-csrfToken"]`)
.getAttribute("content");
const session1 = scparser
.parse(get.headers["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "overleaf_session2").value;
const gclb = scparser
.parse(get.headers["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "GCLB").value;
//POST login data
const post = await post_login(csrf, email, password, session1, gclb);
//get necessary data from response
const session2 = scparser
.parse(post["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "overleaf_session2").value;
//GET new csrf token from project page
const projects = await get_projects(session2, gclb);
const csrf2 = parser
.parse(projects.html)
.querySelector(`meta[name="ol-csrfToken"]`)
.getAttribute("content");
//return data
return {
session: session2,
gclb: gclb,
csrf: csrf2,
projects: projects.html
};
}
async function get_login() {
const url = "https://www.overleaf.com/login";
return new Promise((resolve) => {
https.get(url, (res) => {
var data;
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({ html: data, headers: res.headers });
});
});
});
}
async function get_projects(session2, gclb) {
const url = "https://www.overleaf.com/project";
return new Promise((resolve) => {
https.get(
url,
{ headers: { Cookie: `GCLB=${gclb};overleaf_session2=${session2}` } },
(res) => {
var data;
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({ html: data, headers: res.headers });
});
}
);
});
}
async function post_login(_csrf, email, password, session1, gclb) {
const url = "https://www.overleaf.com/login";
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: `GCLB=${gclb};overleaf_session2=${session1}`
}
};
const postData = {
_csrf: _csrf,
email: email,
password: password
};
return new Promise((resolve) => {
var req = https.request(url, options, (res) => {
resolve(res.headers);
});
req.on("error", (e) => {
console.error(e);
});
req.write(JSON.stringify(postData));
req.end();
});
}

最新更新