| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- const puppeteer = require('puppeteer');
- const getCaptcha = require('../Captcha/tesseract');
- const axios = require('axios');
- class icCookie {
- constructor() {
- console.log('启动浏览器服务')
- this.browser = 0
- }
- async getLoginUrl() {
- return new Promise(async (resolve, reject) => {
- const url1 = 'https://ic.ctbu.edu.cn/ic-web/auth/address?finalAddress=https:%2F%2Fic.ctbu.edu.cn&errPageUrl=https:%2F%2Fic.ctbu.edu.cn%2F%23%2Ferror&manager=false&consoleType=16';
- try {
- const res1 = await axios.get(url1, {
- maxRedirects: 5, // 增加最大重定向次数
- validateStatus: function (status) {
- return (status >= 200 && status < 300) || status === 302; // 接受 302 重定向
- }
- });
- let redirectUrl = res1.data.data || res1.headers.location;
- if (!redirectUrl) {
- reject('无法获取登录 URL');
- return;
- }
- resolve(redirectUrl);
- } catch (error) {
- if (error.response) {
- const redirectUrl = error.response.headers.location;
- if (redirectUrl) {
- resolve(redirectUrl);
- } else {
- reject(error);
- }
- } else {
- reject(error);
- }
- }
- });
- }
- async refresh(page) {
- page.evaluate(async () => {
- // window.location.reload();
- await refreshCode();
- });
- }
- async getAuthcode(page) {
- return new Promise(async (resolve, reject) => {
- try {
- let base64Image = '';
- const url = await this.getLoginUrl();
- page.goto(url);
- page.on('response', async (response) => {
- if (response.url().includes('kaptcha?time=')) {
- const buffer = await response.buffer();
- base64Image = buffer.toString('base64');
- const authcodeResult = await getCaptcha(base64Image);
- if (!authcodeResult.success) {
- return await this.refresh(page);
- }
- const authcode = authcodeResult.msg;
- resolve(authcode);
- }
- });
- // 超时处理
- setTimeout(async () => {
- if (base64Image === '') {
- await this.refresh(page);
- }
- }, 5000);
- } catch (error) {
- console.log(error.stack)
- reject(error);
- }
- });
- }
- async tryLogin(page, username, password, authcode) {
- return new Promise(async (resolve, reject) => {
- try {
- await page.waitForSelector('#username');
- await page.waitForSelector('#authcode');
- await page.waitForSelector('#password');
- await page.waitForSelector('#fm1');
- await page.evaluate(async (username, password, authcode) => {
- document.querySelector("#username").value = username;
- document.querySelector("#authcode").value = authcode;
- function checkForm() {
- var key = new RSAUtils.getKeyPair(public_exponent, "", Modulus);
- var reversedPwd = password.split("").reverse().join("");
- var encrypedPwd = RSAUtils.encryptedString(key, reversedPwd);
- document.querySelector("#password").value = encrypedPwd;
- document.querySelector("#fm1").submit();
- return { public_exponent, Modulus, encrypedPwd, authcode };
- }
- return checkForm();
- }, username, password, authcode);
- // 响应处理
- page.on('response', async (response) => {
- if (response.status() >= 300 && response.status() < 400) {
- return resolve();
- }
- if (response.url().includes('login?v=')) {
- const responseText = await response.text();
- if (responseText.includes('验证码输入有误') || responseText.includes('必须录入验证码')) {
- reject({ code: -603, msg: '验证码输入有误' });
- } else if (responseText.includes('用户名或密码错误')) {
- reject({ code: -600, msg: '用户名或密码错误' });
- } else if (responseText.includes('锁定')) {
- reject({ code: -601, msg: '账户被锁定' });
- } else {
- reject({ code: -604, msg: '未知错误' });
- }
- }
- });
- } catch (error) {
- reject({ code: -602, msg: error.message });
- }
- });
- }
- async loading(username, password) {
- if (this.browser.length >= 5) {
- return { code: -666, msg: '并发数量达到上限,请稍后再试' };
- }
- let browser;
- this.browser += 1
- try {
- browser = await puppeteer.launch({
- headless: true,
- timeout: 60000
- });
- const page = await browser.newPage();
- page.setDefaultTimeout(30000);
- const authcode = await this.getAuthcode(page);
- await this.tryLogin(page, username, password, authcode);
- let cookie = await this.getCookie(page);
-
- cookie = cookie.split(';')[0]
- return { code: 0, msg: cookie };
- } catch (error) {
- console.error('登录过程错误:', error);
- return { code: -600, msg: error.message };
- } finally {
- this.browser -= 1
- if (browser) {
- await browser.close();
- }
- }
- }
- async getCookie (page) {
- return new Promise((resolve, reject) => {
- page.on('response', async response => {
- if (response.url().includes('https://ic.ctbu.edu.cn/ic-web//auth/token?uuid=')) {
- // 获取响应头中的 Set-Cookie
- const cookies = response.headers()['set-cookie'];
- if (cookies) {
- resolve(cookies);
- } else {
- reject('No cookies found in response headers');
- }
- }
- });
- });
- };
- }
- let IcCookie = new icCookie()
- module.exports = IcCookie;
|