Skip to content

核心接口

功能

  • 一周课程查询操作
  • 绩点查询操作

后续会增继续增加接口,以支持更多场景。

接口地址

  • 可以在使用案例中查看

登录验证机制

接下来,我们以 无感状态 进行讲解。

认证方式

教务请求服务通过令牌(token)认证,因此每个需要验权的接口,其请求必须包含 token 字段。我们已实现无感的会话认证,已经将token携带在请求信息中,每次请求都会更新token,实现持久会话。

  • getNewToken 函数用于获取新的令牌。它通过向教务系统发送 POST 请求来获取数据。以下是获取新token的getNewToken函数,其代码如下:
js
/**
 * 获取新token的函数
 * @param {string} rawPassword - 原始密码
 * @param {string} user_code - 用户代码
 * @returns {Promise<string|null>} 返回token或null
 */
async function getNewToken(rawPassword, user_code) {
    // 对原始密码进行Base64编码
    const encodedPassword = encodePassword(rawPassword);

    const data = qs.stringify({
        'passwd': encodedPassword,
        'user_code': user_code // 使用传入的user_code
    });

    const config = {
        method: 'post',
        url: 'http://lgjw.hpu.edu.cn/app-ws/ws/app-service/login',
        headers: {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'Origin': 'http://lgjw.hpu.edu.cn',
            'Proxy-Connection': 'keep-alive',
            'Referer': 'http://lgjw.hpu.edu.cn/app-web/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Host': 'lgjw.hpu.edu.cn',
            'Connection': 'keep-alive'
        },
        data: data
    };

    try {
        const response = await axios(config);
        const businessData = response.data.business_data;
        const decodedData = Buffer.from(businessData, 'base64').toString('utf8');
        const token = JSON.parse(decodedData).token; // 提取token字段
        return token; // 直接返回token
    } catch (error) {
        console.error('获取新token失败:', error.response ? error.response.data : error.message);
        return null;
    }
}
/**
 * 获取新token的函数
 * @param {string} rawPassword - 原始密码
 * @param {string} user_code - 用户代码
 * @returns {Promise<string|null>} 返回token或null
 */
async function getNewToken(rawPassword, user_code) {
    // 对原始密码进行Base64编码
    const encodedPassword = encodePassword(rawPassword);

    const data = qs.stringify({
        'passwd': encodedPassword,
        'user_code': user_code // 使用传入的user_code
    });

    const config = {
        method: 'post',
        url: 'http://lgjw.hpu.edu.cn/app-ws/ws/app-service/login',
        headers: {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'Origin': 'http://lgjw.hpu.edu.cn',
            'Proxy-Connection': 'keep-alive',
            'Referer': 'http://lgjw.hpu.edu.cn/app-web/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Host': 'lgjw.hpu.edu.cn',
            'Connection': 'keep-alive'
        },
        data: data
    };

    try {
        const response = await axios(config);
        const businessData = response.data.business_data;
        const decodedData = Buffer.from(businessData, 'base64').toString('utf8');
        const token = JSON.parse(decodedData).token; // 提取token字段
        return token; // 直接返回token
    } catch (error) {
        console.error('获取新token失败:', error.response ? error.response.data : error.message);
        return null;
    }
}

接口方法

本节将提供目前暴露的接口表,方便快速查询。

js
const express = require('express');
const { getCourseSchedule, getNewToken } = require('./course.js');
const { getGrades } = require('./grade.js'); // 导入getGrades函数

const app = express();
const port = 3000;

/**
 * 获取课程数据的API接口
 * 访问示例: http://localhost:3000/get-course-data?rawPassword=yourPassword&user_code=yourUserCode
 */
app.get('/get-course-data', async (req, res) => {
    const { rawPassword, user_code } = req.query;

    if (!rawPassword || !user_code) {
        return res.status(400).json({ error: '缺少 rawPassword 或 user_code' });
    }

    try {
        const token = await getNewToken(rawPassword, user_code); // 传递user_code

        if (token) {
            const courseData = await getCourseSchedule(token);
            res.json(courseData);
        } else {
            res.status(500).json({ error: '未能获取到token' });
        }
    } catch (error) {
        res.status(500).json({ error: '发生错误', details: error.message });
    }
});

/**
 * 获取成绩数据的API接口
 * 访问示例: http://localhost:3000/get-grade-data?rawPassword=yourPassword&user_code=yourUserCode
 */
app.get('/get-grade-data', async (req, res) => {
    const { rawPassword, user_code } = req.query;

    if (!rawPassword || !user_code) {
        return res.status(400).json({ error: '缺少 rawPassword 或 user_code' });
    }

    try {
        const gradeData = await getGrades(rawPassword, user_code); // 传递参数

        if (gradeData && gradeData.length > 0) {
            res.json(gradeData);
        } else {
            res.status(500).json({ error: '未能获取到成绩数据' });
        }
    } catch (error) {
        res.status(500).json({ error: '发生错误', details: error.message });
    }
});

app.listen(port, () => {
    console.log(`服务器正在运行在 http://localhost:${port}`);
});
const express = require('express');
const { getCourseSchedule, getNewToken } = require('./course.js');
const { getGrades } = require('./grade.js'); // 导入getGrades函数

const app = express();
const port = 3000;

/**
 * 获取课程数据的API接口
 * 访问示例: http://localhost:3000/get-course-data?rawPassword=yourPassword&user_code=yourUserCode
 */
app.get('/get-course-data', async (req, res) => {
    const { rawPassword, user_code } = req.query;

    if (!rawPassword || !user_code) {
        return res.status(400).json({ error: '缺少 rawPassword 或 user_code' });
    }

    try {
        const token = await getNewToken(rawPassword, user_code); // 传递user_code

        if (token) {
            const courseData = await getCourseSchedule(token);
            res.json(courseData);
        } else {
            res.status(500).json({ error: '未能获取到token' });
        }
    } catch (error) {
        res.status(500).json({ error: '发生错误', details: error.message });
    }
});

/**
 * 获取成绩数据的API接口
 * 访问示例: http://localhost:3000/get-grade-data?rawPassword=yourPassword&user_code=yourUserCode
 */
app.get('/get-grade-data', async (req, res) => {
    const { rawPassword, user_code } = req.query;

    if (!rawPassword || !user_code) {
        return res.status(400).json({ error: '缺少 rawPassword 或 user_code' });
    }

    try {
        const gradeData = await getGrades(rawPassword, user_code); // 传递参数

        if (gradeData && gradeData.length > 0) {
            res.json(gradeData);
        } else {
            res.status(500).json({ error: '未能获取到成绩数据' });
        }
    } catch (error) {
        res.status(500).json({ error: '发生错误', details: error.message });
    }
});

app.listen(port, () => {
    console.log(`服务器正在运行在 http://localhost:${port}`);
});

本文档遵循 MIT 协议