|
|
@@ -26,11 +26,19 @@ app.use(cookieParser());
|
|
|
let autoLoginConfig = {};
|
|
|
try {
|
|
|
const configPath = join(__dirname, 'auto-login-config.json');
|
|
|
+ console.log('正在加载自动登录配置文件:', configPath);
|
|
|
const configData = readFileSync(configPath, 'utf-8');
|
|
|
autoLoginConfig = JSON.parse(configData);
|
|
|
- console.log('已加载自动登录配置:', Object.keys(autoLoginConfig).join(', '));
|
|
|
+ console.log('✓ 已加载自动登录配置');
|
|
|
+ console.log(' 配置的网站数量:', Object.keys(autoLoginConfig).length);
|
|
|
+ console.log(' 网站列表:', Object.keys(autoLoginConfig).join(', '));
|
|
|
+ Object.keys(autoLoginConfig).forEach(siteId => {
|
|
|
+ const site = autoLoginConfig[siteId];
|
|
|
+ console.log(` - ${siteId}: ${site.name} (${site.loginMethod})`);
|
|
|
+ });
|
|
|
} catch (error) {
|
|
|
- console.error('加载自动登录配置失败:', error.message);
|
|
|
+ console.error('✗ 加载自动登录配置失败:', error.message);
|
|
|
+ console.error(' 错误堆栈:', error.stack);
|
|
|
console.log('将使用默认配置');
|
|
|
}
|
|
|
|
|
|
@@ -177,11 +185,20 @@ async function handleRSAEncryptedFormLogin(config, credentials) {
|
|
|
const { targetBaseUrl, loginUrl, loginMethodConfig } = config;
|
|
|
const { publicKey, usernameField, passwordField, captchaField, captchaRequired, contentType, successCode, successField } = loginMethodConfig;
|
|
|
|
|
|
+ console.log('=== RSA 加密表单登录 ===');
|
|
|
+ console.log(`目标URL: ${targetBaseUrl}${loginUrl}`);
|
|
|
+ console.log(`用户名: ${credentials.username}`);
|
|
|
+ console.log(`密码: ${'*'.repeat(credentials.password.length)}`);
|
|
|
+ console.log(`内容类型: ${contentType}`);
|
|
|
+ console.log(`成功标识字段: ${successField || 'code'}, 成功值: ${successCode}`);
|
|
|
+
|
|
|
// 加密用户名和密码
|
|
|
const usernameEncrypted = encryptWithRSA(credentials.username, publicKey);
|
|
|
const passwordEncrypted = encryptWithRSA(credentials.password, publicKey);
|
|
|
|
|
|
console.log('用户名和密码已加密');
|
|
|
+ console.log(`加密后用户名长度: ${usernameEncrypted.length}`);
|
|
|
+ console.log(`加密后密码长度: ${passwordEncrypted.length}`);
|
|
|
|
|
|
// 构建请求数据
|
|
|
const requestData = {
|
|
|
@@ -207,6 +224,10 @@ async function handleRSAEncryptedFormLogin(config, credentials) {
|
|
|
requestBody = requestData;
|
|
|
}
|
|
|
|
|
|
+ console.log(`发送登录请求到: ${targetBaseUrl}${loginUrl}`);
|
|
|
+ console.log(`请求头:`, JSON.stringify(headers, null, 2));
|
|
|
+ console.log(`请求体长度: ${requestBody.length} 字符`);
|
|
|
+
|
|
|
const loginResponse = await axios.post(
|
|
|
`${targetBaseUrl}${loginUrl}`,
|
|
|
requestBody,
|
|
|
@@ -220,17 +241,29 @@ async function handleRSAEncryptedFormLogin(config, credentials) {
|
|
|
}
|
|
|
);
|
|
|
|
|
|
+ console.log(`登录响应状态码: ${loginResponse.status}`);
|
|
|
+ console.log(`响应头:`, JSON.stringify(loginResponse.headers, null, 2));
|
|
|
+ console.log(`响应数据:`, JSON.stringify(loginResponse.data, null, 2));
|
|
|
+
|
|
|
// 检查登录是否成功
|
|
|
const responseData = loginResponse.data || {};
|
|
|
const successValue = successField ? responseData[successField] : responseData.code;
|
|
|
|
|
|
+ console.log(`成功标识值: ${successValue}, 期望值: ${successCode}`);
|
|
|
+
|
|
|
if (successValue === successCode) {
|
|
|
+ const cookies = loginResponse.headers['set-cookie'] || [];
|
|
|
+ console.log(`登录成功!获取到 ${cookies.length} 个 Cookie`);
|
|
|
+ cookies.forEach((cookie, index) => {
|
|
|
+ console.log(`Cookie ${index + 1}: ${cookie.substring(0, 100)}...`);
|
|
|
+ });
|
|
|
return {
|
|
|
success: true,
|
|
|
- cookies: loginResponse.headers['set-cookie'] || [],
|
|
|
+ cookies: cookies,
|
|
|
response: loginResponse.data
|
|
|
};
|
|
|
} else {
|
|
|
+ console.error(`登录失败!响应:`, responseData);
|
|
|
return {
|
|
|
success: false,
|
|
|
message: responseData.msg || responseData.message || '登录失败',
|
|
|
@@ -244,6 +277,13 @@ async function handlePlainFormLogin(config, credentials) {
|
|
|
const { targetBaseUrl, loginUrl, loginMethodConfig } = config;
|
|
|
const { usernameField, passwordField, captchaField, contentType, successCode, successField } = loginMethodConfig;
|
|
|
|
|
|
+ console.log('=== 普通表单登录 ===');
|
|
|
+ console.log(`目标URL: ${targetBaseUrl}${loginUrl}`);
|
|
|
+ console.log(`用户名: ${credentials.username}`);
|
|
|
+ console.log(`密码: ${'*'.repeat(credentials.password.length)}`);
|
|
|
+ console.log(`内容类型: ${contentType}`);
|
|
|
+ console.log(`成功标识字段: ${successField || 'code'}, 成功值: ${successCode}`);
|
|
|
+
|
|
|
// 构建请求数据
|
|
|
const requestData = {
|
|
|
[usernameField]: credentials.username,
|
|
|
@@ -268,6 +308,10 @@ async function handlePlainFormLogin(config, credentials) {
|
|
|
requestBody = requestData;
|
|
|
}
|
|
|
|
|
|
+ console.log(`发送登录请求到: ${targetBaseUrl}${loginUrl}`);
|
|
|
+ console.log(`请求头:`, JSON.stringify(headers, null, 2));
|
|
|
+ console.log(`请求体:`, contentType === 'application/json' ? requestBody : requestBody.substring(0, 200) + '...');
|
|
|
+
|
|
|
const loginResponse = await axios.post(
|
|
|
`${targetBaseUrl}${loginUrl}`,
|
|
|
requestBody,
|
|
|
@@ -281,17 +325,28 @@ async function handlePlainFormLogin(config, credentials) {
|
|
|
}
|
|
|
);
|
|
|
|
|
|
+ console.log(`登录响应状态码: ${loginResponse.status}`);
|
|
|
+ console.log(`响应数据:`, JSON.stringify(loginResponse.data, null, 2));
|
|
|
+
|
|
|
// 检查登录是否成功
|
|
|
const responseData = loginResponse.data || {};
|
|
|
const successValue = successField ? responseData[successField] : responseData.code;
|
|
|
|
|
|
+ console.log(`成功标识值: ${successValue}, 期望值: ${successCode}`);
|
|
|
+
|
|
|
if (successValue === successCode) {
|
|
|
+ const cookies = loginResponse.headers['set-cookie'] || [];
|
|
|
+ console.log(`登录成功!获取到 ${cookies.length} 个 Cookie`);
|
|
|
+ cookies.forEach((cookie, index) => {
|
|
|
+ console.log(`Cookie ${index + 1}: ${cookie.substring(0, 100)}...`);
|
|
|
+ });
|
|
|
return {
|
|
|
success: true,
|
|
|
- cookies: loginResponse.headers['set-cookie'] || [],
|
|
|
+ cookies: cookies,
|
|
|
response: loginResponse.data
|
|
|
};
|
|
|
} else {
|
|
|
+ console.error(`登录失败!响应:`, responseData);
|
|
|
return {
|
|
|
success: false,
|
|
|
message: responseData.msg || responseData.message || '登录失败',
|
|
|
@@ -302,28 +357,48 @@ async function handlePlainFormLogin(config, credentials) {
|
|
|
|
|
|
// 通用的自动登录端点
|
|
|
app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
+ const startTime = Date.now();
|
|
|
+ const requestId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
|
+
|
|
|
try {
|
|
|
const { siteId } = req.params;
|
|
|
- console.log(`开始自动登录流程,网站ID: ${siteId}`);
|
|
|
+ console.log('\n' + '='.repeat(80));
|
|
|
+ console.log(`[${requestId}] 开始自动登录流程`);
|
|
|
+ console.log(`[${requestId}] 时间: ${new Date().toISOString()}`);
|
|
|
+ console.log(`[${requestId}] 网站ID: ${siteId}`);
|
|
|
+ console.log(`[${requestId}] 客户端IP: ${req.ip || req.connection.remoteAddress}`);
|
|
|
+ console.log(`[${requestId}] User-Agent: ${req.get('user-agent') || 'Unknown'}`);
|
|
|
|
|
|
// 获取网站配置
|
|
|
const config = autoLoginConfig[siteId];
|
|
|
if (!config) {
|
|
|
+ console.error(`[${requestId}] 错误: 未找到网站ID "${siteId}" 的配置`);
|
|
|
+ console.error(`[${requestId}] 可用的网站ID: ${Object.keys(autoLoginConfig).join(', ') || '无'}`);
|
|
|
return res.status(404).json({
|
|
|
success: false,
|
|
|
- message: `未找到网站ID "${siteId}" 的配置`
|
|
|
+ message: `未找到网站ID "${siteId}" 的配置`,
|
|
|
+ availableSites: Object.keys(autoLoginConfig)
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- console.log(`网站名称: ${config.name}`);
|
|
|
+ console.log(`[${requestId}] 网站名称: ${config.name}`);
|
|
|
+ console.log(`[${requestId}] 目标地址: ${config.targetBaseUrl}`);
|
|
|
+ console.log(`[${requestId}] 登录方法: ${config.loginMethod}`);
|
|
|
|
|
|
// 获取登录凭据(优先使用环境变量)
|
|
|
+ const envUsername = process.env[config.credentials.envUsername];
|
|
|
+ const envPassword = process.env[config.credentials.envPassword];
|
|
|
const credentials = {
|
|
|
- username: process.env[config.credentials.envUsername] || config.credentials.username,
|
|
|
- password: process.env[config.credentials.envPassword] || config.credentials.password
|
|
|
+ username: envUsername || config.credentials.username,
|
|
|
+ password: envPassword || config.credentials.password
|
|
|
};
|
|
|
|
|
|
+ console.log(`[${requestId}] 凭据来源: ${envUsername ? '环境变量' : '配置文件'}`);
|
|
|
+ console.log(`[${requestId}] 用户名: ${credentials.username}`);
|
|
|
+ console.log(`[${requestId}] 密码: ${'*'.repeat(credentials.password.length)}`);
|
|
|
+
|
|
|
if (!credentials.username || !credentials.password) {
|
|
|
+ console.error(`[${requestId}] 错误: 登录凭据未配置`);
|
|
|
return res.status(400).json({
|
|
|
success: false,
|
|
|
message: '登录凭据未配置'
|
|
|
@@ -332,6 +407,7 @@ app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
|
|
|
// 根据登录方法处理登录
|
|
|
let loginResult;
|
|
|
+ console.log(`[${requestId}] 开始执行登录...`);
|
|
|
switch (config.loginMethod) {
|
|
|
case 'rsa-encrypted-form':
|
|
|
loginResult = await handleRSAEncryptedFormLogin(config, credentials);
|
|
|
@@ -340,6 +416,7 @@ app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
loginResult = await handlePlainFormLogin(config, credentials);
|
|
|
break;
|
|
|
default:
|
|
|
+ console.error(`[${requestId}] 错误: 不支持的登录方法: ${config.loginMethod}`);
|
|
|
return res.status(400).json({
|
|
|
success: false,
|
|
|
message: `不支持的登录方法: ${config.loginMethod}`
|
|
|
@@ -347,20 +424,29 @@ app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
}
|
|
|
|
|
|
if (!loginResult.success) {
|
|
|
- console.error('登录失败:', loginResult.message);
|
|
|
+ console.error(`[${requestId}] 登录失败:`, loginResult.message);
|
|
|
+ console.error(`[${requestId}] 失败响应:`, JSON.stringify(loginResult.response, null, 2));
|
|
|
+ const duration = Date.now() - startTime;
|
|
|
+ console.log(`[${requestId}] 总耗时: ${duration}ms`);
|
|
|
+ console.log('='.repeat(80) + '\n');
|
|
|
return res.status(500).json({
|
|
|
success: false,
|
|
|
- message: loginResult.message
|
|
|
+ message: loginResult.message,
|
|
|
+ response: loginResult.response
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- console.log('登录成功!');
|
|
|
+ console.log(`[${requestId}] 登录成功!`);
|
|
|
|
|
|
// 解析 Cookie
|
|
|
const cookieData = parseCookies(loginResult.cookies);
|
|
|
- console.log('获取到 Cookie 数量:', cookieData.length);
|
|
|
+ console.log(`[${requestId}] 解析到 ${cookieData.length} 个 Cookie:`);
|
|
|
+ cookieData.forEach((cookie, index) => {
|
|
|
+ console.log(`[${requestId}] Cookie ${index + 1}: ${cookie.name} = ${cookie.value.substring(0, 20)}...`);
|
|
|
+ });
|
|
|
|
|
|
// 生成跳转 HTML
|
|
|
+ console.log(`[${requestId}] 生成跳转页面,目标: http://${config.targetHost}/`);
|
|
|
const html = generateRedirectHTML(
|
|
|
cookieData,
|
|
|
config.targetHost,
|
|
|
@@ -368,22 +454,42 @@ app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
);
|
|
|
|
|
|
// 在响应头中设置 Cookie
|
|
|
- loginResult.cookies.forEach(cookie => {
|
|
|
+ console.log(`[${requestId}] 设置响应头 Cookie...`);
|
|
|
+ loginResult.cookies.forEach((cookie, index) => {
|
|
|
// 修改 Cookie 的 Domain,移除端口号
|
|
|
let modifiedCookie = cookie.replace(/Domain=[^;]+/i, `Domain=${config.targetDomain}`);
|
|
|
res.setHeader('Set-Cookie', modifiedCookie);
|
|
|
+ console.log(`[${requestId}] 设置 Cookie ${index + 1}: ${modifiedCookie.substring(0, 80)}...`);
|
|
|
});
|
|
|
|
|
|
+ const duration = Date.now() - startTime;
|
|
|
+ console.log(`[${requestId}] 总耗时: ${duration}ms`);
|
|
|
+ console.log(`[${requestId}] 返回跳转页面`);
|
|
|
+ console.log('='.repeat(80) + '\n');
|
|
|
+
|
|
|
res.send(html);
|
|
|
} catch (error) {
|
|
|
- console.error('自动登录错误:', error.message);
|
|
|
+ const duration = Date.now() - startTime;
|
|
|
+ console.error(`[${requestId}] 自动登录异常:`, error.message);
|
|
|
+ console.error(`[${requestId}] 错误堆栈:`, error.stack);
|
|
|
if (error.response) {
|
|
|
- console.error('响应状态:', error.response.status);
|
|
|
- console.error('响应数据:', error.response.data);
|
|
|
+ console.error(`[${requestId}] 响应状态:`, error.response.status);
|
|
|
+ console.error(`[${requestId}] 响应头:`, JSON.stringify(error.response.headers, null, 2));
|
|
|
+ console.error(`[${requestId}] 响应数据:`, JSON.stringify(error.response.data, null, 2));
|
|
|
+ }
|
|
|
+ if (error.request) {
|
|
|
+ console.error(`[${requestId}] 请求信息:`, {
|
|
|
+ url: error.config?.url,
|
|
|
+ method: error.config?.method,
|
|
|
+ headers: error.config?.headers
|
|
|
+ });
|
|
|
}
|
|
|
+ console.log(`[${requestId}] 总耗时: ${duration}ms`);
|
|
|
+ console.log('='.repeat(80) + '\n');
|
|
|
res.status(500).json({
|
|
|
success: false,
|
|
|
- message: '自动登录失败: ' + error.message
|
|
|
+ message: '自动登录失败: ' + error.message,
|
|
|
+ error: process.env.NODE_ENV === 'development' ? error.stack : undefined
|
|
|
});
|
|
|
}
|
|
|
});
|