背景:最近有個需求是須要用 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