基于这位大佬的项目将访客变成独立的账号密码,cf worker部署Fuclaude号池

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

const CONFIG = {
    ORIGINAL_WEBSITE: "https://demo.fuclaude.com",
    SESSION_KEYS: ["sk-ant",
        "sk-ant",
        "sk-ant",
        "sk-ant",
        "sk-ant",
        "sk-ant"], // 在此处加入你的 session_key
    KEY_NAMES: ["c1", "c2", "c3", "c4", "c5", "c6"], // 在此处加入你的 会话名称
    SITE_PASSWORD: "password",  // 在此处加入你的 站点密码
    GUEST_ACCOUNTS: {
        //在此处加入你的访客账号 "account": "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 (CONFIG.GUEST_ACCOUNTS[username.trim()]  === undefined) {
                return new Response('不存在该用户', {
                    status: 400,
                    headers: {'Content-Type': 'text/plain; charset=utf-8'}
                });
            }
            if (CONFIG.GUEST_ACCOUNTS[username] !== guestPassword) {
                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>lsy的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>lsy的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>`;
23 个赞

太强了,佬:+1:

感谢大佬分享

mark,感谢分享!

感谢分享mark claude共享

感谢大佬分享

为什么 部署之后登陆失败啊,一直有这个困惑

我拿楼主引用的那篇帖子,自己魔改了下代码,用KV空间加入账号状态验证


当时也遇到这个问题,百思不得其解
结果最后,,,,,
是因为KV空间写入超出免费额度了 :tieba_087:
不知道有没有参考价值
(看看路径、session_key是否有效)

好的,楼主的这篇不涉及到kv
kv的我用了也是有问题,报1101的错误

同问,等大佬解答了。