基于这位大佬的项目修改了一下样式,cf worker部署Fuclaude号池

先感谢这位大佬,我在这个项目基础上修改了一下,面向ChatGPT编程,添加了白天黑夜模式的样式,以及自定义账号名,本来想跟kv结合一下,奈何技术不够,正在研究,先把代码分享一下,希望佬友们提出意见建议

const CONFIG = {
  ORIGINAL_WEBSITE: "https://demo.fuclaude.com //可以用自己部署的也可以用始皇的,建议直接用始皇的比较稳",
  SESSION_KEYS: [ "sk-ant-1", 
                  "sk-ant-2",
                  "sk-ant-3",
                  "sk-ant-4"  ], // 在此处加入你的 session_key
  KEY_NAMES: ["a", "b", "c" //自己设置账号名],
  SITE_PASSWORD: "YOUR_SITE_PASSWORD",
  GUEST_PASSWORD: "YOUR_GUEST_PASSWORD"
};

export default {
  async fetch(request, env, ctx) {
    return await handleRequest(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');
    const selectedKeyIndex = formData.get('session_key_index');
    let body = { 'session_key': CONFIG.SESSION_KEYS[selectedKeyIndex] };
    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;
}

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>Keyikai的Claude公益站</title>
  <style>
    :root {
      --bg-dark: rgb(33, 33, 33);
      --container-bg-dark: rgb(45, 45, 45);
      --text-dark: #e0e0e0;
      --bg-light: #edeadf;
      --container-bg-light: #f3f1ea;
      --text-light: #333333;
      --button-bg: #ab5235;
    }
    @media (prefers-color-scheme: dark) {
      body, html {
        background: var(--bg-dark);
        color: var(--text-dark);
      }
      .form-container {
        background: var(--container-bg-dark);
      }
      input[type="text"], input[type="password"] {
        background-color: #3a3937;
        border: 1px solid #4a4945;
        color: var(--text-dark);
      }
    }
    @media (prefers-color-scheme: light) {
      body, html {
        background: var(--bg-light);
        color: var(--text-light);
      }
      .form-container {
        background: var(--container-bg-light);
      }
      input[type="text"], input[type="password"] {
        background-color: #ffffff;
        border: 1px solid #cccccc;
        color: var(--text-light);
      }
    }
    body, html {
      height: 100dvh;
      margin: 0;
      overflow: hidden;
      font-family: system-ui, sans-serif;
    }
    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100dvh;
      padding: 20px;
      box-sizing: border-box;
    }
    .form-container {
      padding: 40px;
      border-radius: 10px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      width: 100%;
      max-width: 400px;
    }
    h1 {
      text-align: center;
      margin-bottom: 30px;
      font-size: 28px;
    }
    .form-group {
      margin-bottom: 20px;
    }
    label {
      display: block;
      margin-bottom: 8px;
      font-weight: 500;
    }
    input[type="text"], input[type="password"] {
      width: 100%;
      padding: 12px;
      box-sizing: border-box;
      font-size: 16px;
    }
    input[type="text"]:focus, input[type="password"]:focus {
      outline: none;
      border-color: var(--button-bg);
    }
    button {
      width: 100%;
      padding: 12px;
      background-color: var(--button-bg);
      color: white;
      border: none;
      border-radius: 4px;
      font-size: 16px;
      font-weight: 600;
      cursor: pointer;
      margin-bottom: 10px;
    }
    .key-buttons {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 13px;
      margin-bottom: 10px;
    }
    .key-button {
      flex: 1;
      padding: 15px;
      color: white;
      background-color: var(--button-bg);
      border: none;
      border-radius: 8px;
      cursor: pointer;
      font-size: 16px;
      font-weight: 500;
      text-align: center;
      margin-bottom: 0;
    }
    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="form-container" id="keySelection">
      <h1>Keyikai的Claude公益站</h1>
      <div class="key-buttons" id="keyButtons"></div>
    </div>
    <div class="form-container hidden" id="guestLogin">
      <h1>访客登录</h1>
      <form method="POST">
        <input type="hidden" name="login_type" value="guest">
        <input type="hidden" id="guest_selected_key_index" name="session_key_index" value="">
        <div class="form-group">
          <label for="username">用户名:</label>
          <input type="text" id="username" name="username" placeholder="用于隔离会话,填一个别人猜不到的即可" required>
        </div>
        <div class="form-group">
          <label for="guest_password">访客密码:</label>
          <input type="password" id="guest_password" name="guest_password" placeholder="输入访客密码" required>
        </div>
        <button type="submit">登录</button>
      </form>
      <button class="switch-btn" onclick="toggleForm()">切换到站点密码登录</button>
      <button class="switch-btn" onclick="backToKeySelection()">返回选择通道</button>
    </div>
    <div class="form-container hidden" id="siteLogin">
      <h1>站点密码登录</h1>
      <form method="POST">
        <input type="hidden" name="login_type" value="site">
        <input type="hidden" id="site_selected_key_index" name="session_key_index" value="">
        <div class="form-group">
          <label for="site_password">站点密码:</label>
          <input type="password" id="site_password" name="site_password" placeholder="输入站点密码" required>
        </div>
        <button type="submit">登录</button>
      </form>
      <button class="switch-btn" onclick="toggleForm()">切换到访客登录</button>
      <button class="switch-btn" onclick="backToKeySelection()">返回选择通道</button>
    </div>
  </div>
  <script>
    const keyCount = ${CONFIG.SESSION_KEYS.length};
    const keyNames = ${JSON.stringify(CONFIG.KEY_NAMES)};
    function createKeyButtons() {
      const container = document.getElementById('keyButtons');
      for (let i = 0; i < keyCount; i++) {
        const button = document.createElement('button');
        button.type = 'button';
        button.className = 'key-button';
        button.textContent = keyNames[i] || \`通道 \${i + 1}\`;
        button.onclick = () => selectKey(i);
        container.appendChild(button);
      }
    }
    function selectKey(index) {
      document.getElementById('guest_selected_key_index').value = index;
      document.getElementById('site_selected_key_index').value = index;
      document.getElementById('keySelection').classList.add('hidden');
      document.getElementById('guestLogin').classList.remove('hidden');
    }
    function backToKeySelection() {
      document.getElementById('keySelection').classList.remove('hidden');
      document.getElementById('guestLogin').classList.add('hidden');
      document.getElementById('siteLogin').classList.add('hidden');
    }
    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');
      } else {
        guestLogin.classList.add('hidden');
        siteLogin.classList.remove('hidden');
      }
    }
    createKeyButtons();
  </script>
</body>
</html>`;

11 个赞

感谢分享。:hear_no_evil:

萌萌白盼着用上claude那一天。

1 个赞

感谢大佬分享

1 个赞

可以看看始皇的教程,注册账号的话 接码用5sim,充个1$能用很多次,选最便宜那个就可以

1 个赞


这是什么意思啊

跟老哥一样,我也想问问楼主为什么我用电脑登录就会报错“登录过程中发生错误”,但是移动端就很正常?

大佬太强了,我连编程都不会 :tieba_009: