Session 来自 node-fetch 的 cookie 无效?
Session cookie from node-fetch is invalid?
我正在编写 javascript 程序(用于 github 操作),但是 运行 遇到了问题。
我试图使用我的凭据和 csrf 令牌登录 www.overleaf.com and access the page https://www.overleaf.com/project after generating a session cookie by sending a POST request to https://www.overleaf.com/login。
响应按预期在 set-cookie header 中包含请求的令牌,但是,当我尝试访问 https://www.overleaf.com/project via GET, I get redirected back to https://www.overleaf.com/login
时
复制保存在我的浏览器中的 session cookie 时,请求工作正常。
我尝试在命令行中使用 cURL 做同样的事情,它在那里工作。
我相当确定我的身份验证请求已被 Overleaf 的服务器接受,因为我曾尝试故意错误地发送密码或 csrf 令牌,在这两种情况下,响应都没有给我新的 session cookie但发送旧的。
如果有人知道出了什么问题,我将非常感谢您的意见。
这是在终端中起作用的,我试图在 javascript 中用 node-fetch:
复制它
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
获取 cookie 和 csrf 令牌和
curl -v https://www.overleaf.com/project --cookie "overleaf_session2=returnedsessioncookie; GCLB=someothercookie"
作为 returns 我项目的 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,如果他们这样做,那么网络将是一个不安全的地方,因为例如 Whosebug 可以访问我的 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();
});
}
我正在编写 javascript 程序(用于 github 操作),但是 运行 遇到了问题。
我试图使用我的凭据和 csrf 令牌登录 www.overleaf.com and access the page https://www.overleaf.com/project after generating a session cookie by sending a POST request to https://www.overleaf.com/login。
响应按预期在 set-cookie header 中包含请求的令牌,但是,当我尝试访问 https://www.overleaf.com/project via GET, I get redirected back to https://www.overleaf.com/login
时
复制保存在我的浏览器中的 session cookie 时,请求工作正常。
我尝试在命令行中使用 cURL 做同样的事情,它在那里工作。
我相当确定我的身份验证请求已被 Overleaf 的服务器接受,因为我曾尝试故意错误地发送密码或 csrf 令牌,在这两种情况下,响应都没有给我新的 session cookie但发送旧的。
如果有人知道出了什么问题,我将非常感谢您的意见。
这是在终端中起作用的,我试图在 javascript 中用 node-fetch:
复制它
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
获取 cookie 和 csrf 令牌和
curl -v https://www.overleaf.com/project --cookie "overleaf_session2=returnedsessioncookie; GCLB=someothercookie"
作为 returns 我项目的 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,如果他们这样做,那么网络将是一个不安全的地方,因为例如 Whosebug 可以访问我的 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();
});
}