背景:最近有个需求是须要用 node 模拟咱们网站的客户端请求拿到数据,可是每一个请求都须要登陆成功后携带 cookie 的 sessionId 才能正常发送,那么怎样才能用 node 去模拟客户端的单点登陆,拿到 cookie 呢?html
用浏览器查看了一下登陆的整个过程,首先,输入完用户名密码,cas 服务器会给一个 ticket 的东西,而后带着这个 ticket 去访问重定向的地址,这个时候,cas 服务器就会把 JSESSIONID 传递回来了,自动保存到浏览器的 cookie 中。node
最终解决办法:使用 puppeteer (相似爬虫)模拟用户登陆,登陆成功后获取网站的 cookiegit
话很少说,上代码!github
const puppeteer = require('puppeteer');
let loginUrl = 访问地址;
const user = 登陆名;
const password = 密码;
let cookie;
(async () => {
const browser = await puppeteer.launch({headless: true});//打开浏览器, headless 为 false 的时候,能够看见浏览器的整个过程
const page = await browser.newPage();//打开一个空白页
await page.goto(loginUrl);//打开网站
await page.type('input[name="username"]', user); // 输入用户名的 input (也能够是其余的选择器)
await page.type('input[name="password"]', password); // 输入密码的 input (也能够是其余的选择器)
await page.click('button'); // 点击登陆的按钮 (也能够是其余的选择器)
await page.waitForNavigation({
waitUntil: 'load',
timeout: 0
});//等待页面加载出来,等同于window.onload
const cookies = await page.cookies();
cookies.map(v => {
if (v.name === 'JSESSIONID') {
cookie = v.value; // 这个就是登陆成功后获得的 cookie 里的 JSESSIONID
--- 下面的代码是我要把用户的信息和 JSESSIONID 存到一个公共文件里,用不到的能够忽略如下代码 ---
let data = {
"username": 用户名,
"cookie": "JSESSIONID="+ cookie +"; Path=/; HttpOnly"
}
fs.writeFile('./user.json', JSON.stringify(data), (err) => {
if (err) {
console.log(err);
} else {
console.log('存入 user 信息成功!');
}
})
}
});
await browser.close();//关掉浏览器
})();复制代码
ps:这里记录一个坑,使用 puppeteer load 的网页可能很大,须要很长的时间,超时了之后会在命令行报错 json
TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded复制代码
解决办法:浏览器
把 timeout 设置为 0 参考链接bash
await page.waitForNavigation({
waitUntil: 'load',
timeout: 0
});复制代码
puppeteer简介服务器
puppetter cas sso 参考连接cookie