Fuclaude 共享使用脚本

Cloudflare Worker 代码修改自:

const CONFIG = {
  ORIGINAL_WEBSITE: "https://example.com",
  SESSION_KEYS: ["key1", "key2"], // 在此处加入你的 session_key
  SITE_PASSWORD: "站点密码",
  GUEST_PASSWORD: "访客密码"
};
  
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const url = new URL(request.url);

  if (url.pathname === '/login') {
    return handleRootPath(request, url, true);
  }

  if (url.pathname === '/') {
    return handleRootPath(request, url);
  }

  return proxyRequest(request);
}

async function handleRootPath(request, url, forceLogin = false) {
    const cookie = request.headers.get('Cookie') || '';
  if ((!forceLogin) && cookie.includes('_Secure-next-auth.session-data')) {
    return Response.redirect(`${url.origin}/new`, 302);
  }

  if (request.method === 'POST') {
    return handleLogin(request, url);
  }

  return new Response(formHtml, {
    headers: { 'Content-Type': 'text/html; charset=utf-8' }
  });
}

async function handleLogin(request, url) {
  try {
    const formData = await request.formData();
    const loginType = formData.get('login_type');

    let body = {
      'session_key': getRandomSessionKey()
    };

    if (loginType === 'site') {
      const sitePassword = formData.get('site_password');
      if (sitePassword !== CONFIG.SITE_PASSWORD) {
        return new Response('站点密码错误', {
          status: 403,
          headers: { 'Content-Type': 'text/plain; charset=utf-8' }
        });
      }
    } else if (loginType === 'guest') {
      const username = formData.get('username');
      const guestPassword = formData.get('guest_password');
      
      if (!username || username.trim() === '') {
        return new Response('访客登录必须提供用户名', {
          status: 400,
          headers: { 'Content-Type': 'text/plain; charset=utf-8' }
        });
      }
      
      if (guestPassword !== CONFIG.GUEST_PASSWORD) {
        return new Response('访客密码错误', {
          status: 403,
          headers: { 'Content-Type': 'text/plain; charset=utf-8' }
        });
      }

      body.unique_name = username;
    } else {
      return new Response('无效的登录类型', {
        status: 400,
        headers: { 'Content-Type': 'text/plain; charset=utf-8' }
      });
    }

    const authUrl = `${CONFIG.ORIGINAL_WEBSITE}/manage-api/auth/oauth_token`;

    const apiResponse = await fetch(authUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });

    if (!apiResponse.ok) {
      throw new Error(`API request failed with status ${apiResponse.status}`);
    }

    const respJson = await apiResponse.json();
    const login_url = respJson.login_url || '/';
    return Response.redirect(`https://${url.host}${login_url}`, 302);
  } catch (error) {
    console.error('Login error:', error);
    return new Response('登录过程中发生错误', {
      status: 500,
      headers: { 'Content-Type': 'text/plain; charset=utf-8' }
    });
  }
}

async function proxyRequest(request) {
  const url = new URL(request.url);
  const newUrl = `${CONFIG.ORIGINAL_WEBSITE}${url.pathname}${url.search}`;
  const modifiedRequest = new Request(newUrl, request);
  const response = await fetch(modifiedRequest);
  const contentType = response.headers.get('content-type');
  if (contentType && contentType.includes('text/html') && url.pathname !== '/login_oauth') {
    let html = await response.text();
    const regex = /<div[^>]*>(?=[\s\S]*?<h3[\s\S]*?<\/h3>)(?=[\s\S]*?<p[\s\S]*?<\/p>)(?=[\s\S]*?<div[\s\S]*?<\/div>)[\s\S]*?<\/div>/gi
    html = html.replace(regex, '');
    return new Response(html, {
      headers: response.headers
    })
  }
  return response;
}

function getRandomSessionKey() {
  const keys = CONFIG.SESSION_KEYS;
  const randomIndex = Math.floor(Math.random() * keys.length);
  return keys[randomIndex];
}

const formHtml = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fuclaude 登录</title>
    <style>
        body, html {
            height: 100%;
            margin: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100%;
            padding: 20px;
        }
        .form-container {
            background: white;
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 400px;
        }
        h1 {
            color: #4a5568;
            text-align: center;
            margin-bottom: 30px;
            font-size: 28px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 8px;
            color: #4a5568;
            font-weight: 500;
        }
        input[type="text"] {
            width: 100%;
            padding: 12px;
            border: 1px solid #e2e8f0;
            border-radius: 4px;
            font-size: 16px;
            transition: border-color 0.3s ease;
        }
        input[type="text"]:focus {
            outline: none;
            border-color: #667eea;
        }
        button {
            width: 100%;
            padding: 12px;
            background-color: #667eea;
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: background-color 0.3s ease;
            margin-bottom: 10px;
        }
        button:hover {
            background-color: #5a67d8;
        }
        .switch-btn {
            background-color: #4a5568;
            margin-top: 20px;
        }
        .switch-btn:hover {
            background-color: #2d3748;
        }
        .hidden {
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="form-container" id="guestLogin">
            <h1>访客登录</h1>
            <form method="POST">
                <input type="hidden" name="login_type" value="guest">
                <div class="form-group">
                    <label for="guest_password">访客密码:</label>
                    <input type="text" id="guest_password" name="guest_password" placeholder="输入访客密码" required>
                </div>
                <div class="form-group">
                    <label for="username">用户名:</label>
                    <input type="text" id="username" name="username" placeholder="用于隔离会话,填一个别人猜不到的即可" required>
                </div>
                <button type="submit">登录</button>
            </form>
            <button class="switch-btn" onclick="toggleForm()">切换到站点密码登录</button>
        </div>

        <div class="form-container hidden" id="siteLogin">
            <h1>站点密码登录</h1>
            <form method="POST">
                <input type="hidden" name="login_type" value="site">
                <div class="form-group">
                    <label for="site_password">站点密码:</label>
                    <input type="text" id="site_password" name="site_password" placeholder="输入站点密码" required>
                </div>
                <button type="submit">登录</button>
            </form>
            <button class="switch-btn" onclick="toggleForm()">切换到访客登录</button>
        </div>
    </div>

    <script>
        function toggleForm() {
            const guestLogin = document.getElementById('guestLogin');
            const siteLogin = document.getElementById('siteLogin');
            if (guestLogin.classList.contains('hidden')) {
                guestLogin.classList.remove('hidden');
                siteLogin.classList.add('hidden');
                document.title = "Fuclaude 登录";
            } else {
                guestLogin.classList.add('hidden');
                siteLogin.classList.remove('hidden');
                document.title = "Fuclaude 站点密码登录";
            }
        }
    </script>
</body>
</html>
`;
  1. 修复了 fuclaude 退出登录后会死循环重定向的bug
  2. 支持填入多个 session_key,目前是随机选一个使用
  3. 强制除去询问 Cookie 设置的弹窗

号池版本见:

29 Likes

#Worker添加

佬强

3 Likes

感谢!!

3 Likes

牛呀佬

牛啊啊,大佬

太强了!

我这边使用站点密码登录使用正常,使用访客隔离的时候始终报403 :sob:

用的什么服务器?

Serv00

感谢佬

serv00 的 WAF 把你的流量当攻击给拦了
面板 WWW websites 找到你的网站,Manage->Details


WAF 设置为 Disabled 即可

1 Like

关掉就可以了,谢谢佬!
另外我有一个疑问,为啥正常访问的时候没有问题,使用login_oauth登录就会被WAF拦截呢?

是否站点登录用的都是 login_oauth,理论上是没有区别的,可能浏览器有缓存?serv00的拦截规则我也不清楚。有可能加了 unique_name 之后token变长WAF以为是溢出攻击也不一定

好的,再次感谢大佬

感谢佬

:tieba_013:美美用上

牛蛙

厉害

artifacts是白的是啥原因呀。。