|
|
@@ -101,9 +101,9 @@ function parseCookies(setCookieHeaders) {
|
|
|
}
|
|
|
|
|
|
// 生成跳转 HTML
|
|
|
-function generateRedirectHTML(cookieData, targetHost, targetDomain, requestId = '', customUrl = null) {
|
|
|
+function generateRedirectHTML(cookieData, targetHost, targetDomain, requestId = '', customUrl = null, homeAssistantData = null) {
|
|
|
const targetUrl = customUrl || `http://${targetHost}/`;
|
|
|
- const isHomeAssistant = targetUrl.includes('/auth/authorize');
|
|
|
+ const isHomeAssistant = homeAssistantData !== null;
|
|
|
|
|
|
return `
|
|
|
<!DOCTYPE html>
|
|
|
@@ -157,6 +157,7 @@ function generateRedirectHTML(cookieData, targetHost, targetDomain, requestId =
|
|
|
const targetUrl = '${targetUrl}';
|
|
|
const targetDomain = '${targetDomain}';
|
|
|
const isHomeAssistant = ${isHomeAssistant};
|
|
|
+ const homeAssistantData = ${homeAssistantData ? JSON.stringify(homeAssistantData) : 'null'};
|
|
|
|
|
|
console.log('========================================');
|
|
|
console.log('[浏览器端] 自动登录脚本开始执行');
|
|
|
@@ -165,7 +166,8 @@ function generateRedirectHTML(cookieData, targetHost, targetDomain, requestId =
|
|
|
console.log('[浏览器端] 目标域名:', targetDomain);
|
|
|
console.log('[浏览器端] Cookie 数量:', cookies.length);
|
|
|
console.log('[浏览器端] Cookie 详情:', cookies);
|
|
|
- console.log('[浏览器端] 是否为 Home Assistant 授权流程:', isHomeAssistant);
|
|
|
+ console.log('[浏览器端] 是否为 Home Assistant:', isHomeAssistant);
|
|
|
+ console.log('[浏览器端] Home Assistant 数据:', homeAssistantData);
|
|
|
|
|
|
// 方法1: 尝试直接设置 Cookie(可能因为跨域限制而失败)
|
|
|
if (cookies.length > 0) {
|
|
|
@@ -218,14 +220,83 @@ function generateRedirectHTML(cookieData, targetHost, targetDomain, requestId =
|
|
|
console.log('[浏览器端] 没有 Cookie 需要设置,直接跳转');
|
|
|
}
|
|
|
|
|
|
- // 对于 Home Assistant 授权流程,直接跳转(不需要 iframe)
|
|
|
- if (isHomeAssistant) {
|
|
|
- console.log('[浏览器端] Home Assistant 授权流程,直接跳转到授权端点');
|
|
|
- console.log('[浏览器端] 授权 URL:', targetUrl);
|
|
|
- console.log('[浏览器端] 浏览器将处理授权流程并设置 Cookie');
|
|
|
- console.log('========================================');
|
|
|
- // 立即跳转,让浏览器处理授权流程
|
|
|
- window.location.href = targetUrl;
|
|
|
+ // 对于 Home Assistant,在浏览器端执行登录流程
|
|
|
+ if (isHomeAssistant && homeAssistantData) {
|
|
|
+ console.log('[浏览器端] Home Assistant 登录,在浏览器端执行登录流程');
|
|
|
+ console.log('[浏览器端] 目标 URL:', homeAssistantData.targetBaseUrl);
|
|
|
+ console.log('[浏览器端] 用户名:', homeAssistantData.username);
|
|
|
+
|
|
|
+ // 异步执行登录流程
|
|
|
+ async function loginHomeAssistant() {
|
|
|
+ try {
|
|
|
+ console.log('[浏览器端] 步骤1: 创建登录流程...');
|
|
|
+ const flowResponse = await fetch(homeAssistantData.targetBaseUrl + '/auth/login_flow', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ client_id: homeAssistantData.targetBaseUrl + '/',
|
|
|
+ handler: ['homeassistant', null],
|
|
|
+ redirect_uri: homeAssistantData.targetBaseUrl + '/'
|
|
|
+ }),
|
|
|
+ credentials: 'include'
|
|
|
+ });
|
|
|
+
|
|
|
+ const flowData = await flowResponse.json();
|
|
|
+ console.log('[浏览器端] 流程创建响应:', flowData);
|
|
|
+
|
|
|
+ if (!flowData.flow_id) {
|
|
|
+ throw new Error('无法获取 flow_id');
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('[浏览器端] 步骤2: 提交用户名和密码...');
|
|
|
+ const loginResponse = await fetch(homeAssistantData.targetBaseUrl + '/auth/login_flow/' + flowData.flow_id, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ username: homeAssistantData.username,
|
|
|
+ password: homeAssistantData.password,
|
|
|
+ client_id: homeAssistantData.targetBaseUrl + '/'
|
|
|
+ }),
|
|
|
+ credentials: 'include'
|
|
|
+ });
|
|
|
+
|
|
|
+ const loginData = await loginResponse.json();
|
|
|
+ console.log('[浏览器端] 登录响应:', loginData);
|
|
|
+
|
|
|
+ if (loginData.type === 'create_entry') {
|
|
|
+ console.log('[浏览器端] 登录成功!准备跳转到授权端点...');
|
|
|
+
|
|
|
+ // 构建授权 URL
|
|
|
+ const stateData = {
|
|
|
+ hassUrl: homeAssistantData.targetBaseUrl,
|
|
|
+ clientId: homeAssistantData.targetBaseUrl + '/'
|
|
|
+ };
|
|
|
+ const state = btoa(JSON.stringify(stateData));
|
|
|
+ const redirectUri = homeAssistantData.targetBaseUrl + '/?auth_callback=1';
|
|
|
+ const clientId = homeAssistantData.targetBaseUrl + '/';
|
|
|
+ const authorizeUrl = homeAssistantData.targetBaseUrl + '/auth/authorize?response_type=code&redirect_uri=' + encodeURIComponent(redirectUri) + '&client_id=' + encodeURIComponent(clientId) + '&state=' + encodeURIComponent(state);
|
|
|
+
|
|
|
+ console.log('[浏览器端] 授权 URL:', authorizeUrl);
|
|
|
+ console.log('[浏览器端] 跳转到授权端点...');
|
|
|
+ console.log('========================================');
|
|
|
+
|
|
|
+ window.location.href = authorizeUrl;
|
|
|
+ } else {
|
|
|
+ throw new Error('登录失败: ' + JSON.stringify(loginData));
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('[浏览器端] 登录失败:', error);
|
|
|
+ alert('自动登录失败: ' + error.message + '\\n\\n将跳转到登录页面,请手动登录。');
|
|
|
+ window.location.href = targetUrl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行登录
|
|
|
+ loginHomeAssistant();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -956,19 +1027,22 @@ app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
});
|
|
|
|
|
|
// 生成跳转 HTML(添加更多调试信息)
|
|
|
- // 对于 Home Assistant,如果没有 Cookie,直接跳转到授权端点
|
|
|
+ // 对于 Home Assistant,如果没有 Cookie,让浏览器端完成登录
|
|
|
let redirectUrl = `http://${config.targetHost}/`;
|
|
|
+ let homeAssistantLoginData = null;
|
|
|
+
|
|
|
if (config.loginMethod === 'home-assistant' && cookieData.length === 0) {
|
|
|
- // 构建授权 URL 让浏览器处理
|
|
|
- const stateData = {
|
|
|
- hassUrl: config.targetBaseUrl,
|
|
|
- clientId: `${config.targetBaseUrl}/`
|
|
|
+ console.log(`[${requestId}] Home Assistant 无 Cookie,准备在浏览器端完成登录流程`);
|
|
|
+ // 传递登录信息给浏览器端
|
|
|
+ homeAssistantLoginData = {
|
|
|
+ targetBaseUrl: config.targetBaseUrl,
|
|
|
+ username: credentials.username,
|
|
|
+ password: credentials.password,
|
|
|
+ // 如果后端已获取到 result token,也传递过去
|
|
|
+ resultToken: loginResult.response?.result
|
|
|
};
|
|
|
- const state = Buffer.from(JSON.stringify(stateData)).toString('base64');
|
|
|
- const redirectUri = `${config.targetBaseUrl}/?auth_callback=1`;
|
|
|
- const clientId = `${config.targetBaseUrl}/`;
|
|
|
- redirectUrl = `${config.targetBaseUrl}/auth/authorize?response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&client_id=${encodeURIComponent(clientId)}&state=${encodeURIComponent(state)}`;
|
|
|
- console.log(`[${requestId}] Home Assistant 无 Cookie,跳转到授权端点: ${redirectUrl}`);
|
|
|
+ redirectUrl = config.targetBaseUrl;
|
|
|
+ console.log(`[${requestId}] 将在浏览器端执行 Home Assistant 登录流程`);
|
|
|
}
|
|
|
|
|
|
console.log(`[${requestId}] 生成跳转页面,目标: ${redirectUrl}`);
|
|
|
@@ -977,7 +1051,8 @@ app.get('/api/auto-login/:siteId', async (req, res) => {
|
|
|
config.targetHost,
|
|
|
config.targetDomain,
|
|
|
requestId,
|
|
|
- redirectUrl
|
|
|
+ redirectUrl,
|
|
|
+ homeAssistantLoginData
|
|
|
);
|
|
|
|
|
|
// 在响应头中设置 Cookie
|