node 模拟客户端 cas sso 单点登录获取cookie

2,619 阅读2分钟

背景:最近有个需求是需要用 node 模拟我们网站的客户端请求拿到数据,但是每个请求都需要登录成功后携带 cookie 的 sessionId 才能正常发送,那么怎样才能用 node 去模拟客户端的单点登录,拿到 cookie 呢?

用浏览器查看了一下登录的整个过程,首先,输入完用户名密码,cas 服务器会给一个 ticket 的东西,然后带着这个 ticket 去访问重定向的地址,这个时候,cas 服务器就会把 JSESSIONID 传递回来了,自动保存到浏览器的 cookie 中。

最终解决办法:使用 puppeteer (类似爬虫)模拟用户登录,登录成功后获取网站的 cookie

话不多说,上代码!

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 的网页可能很大,需要很长的时间,超时了以后会在命令行报错 

TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded

解决办法:

把 timeout 设置为 0     参考连接

await page.waitForNavigation({
    waitUntil: 'load',
    timeout: 0
  });

puppeteer简介

puppetter cas sso 参考链接