【由于始皇更新各位移步19、22楼】水一贴,解决始皇的New站怎么通过url传参数避免用户手动输入tk

原理就是通过cf worker设置一个access_token的cookie,这个值可以通过url后缀传参来实现。

一个典型的请求如下:https://YOUR_DOMAIN/setcookie.html?access_token=${tokenKey}

直接通过浏览器访问这个url(get请求)就可以自动配置好cookie同时跳转到对话界面。全过程0用户交互。

不废话,直接代码如下:

const hostname = "https://new.oaifree.com";

async function handleRequest(request) {
  let url = new URL(request.url);
  if (url.pathname === '/setcookie.html') {
    const accessToken = url.searchParams.get('access_token');
    if (accessToken) {
      const response = new Response(null, {
        status: 302,
        headers: {
          'Location': '/',
          'Set-Cookie': `access_token=${accessToken}; Path=/; Secure; HttpOnly`
        }
      });
      return response;
    }
  }
  return fetch(new Request(hostname + url.pathname, request));
}

addEventListener("fetch", (event) => {
  event.respondWith(handleRequest(event.request));
});

同时,由此,改了一版之前奥特曼发的sharetoken的worker:

PS: 我觉得new站比demo站好看多了,所以把demo的部分删了。
感谢这两位大佬的前期工作:

部署方式不变

此外还需要配置 设置–变量–环境变量 里面设置如下两个参数:

PASSWORD: your_customed_share_password
YOUR_DOMAIN: your_customed_proxy_domain
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})
function parseJwt(token) {
  const base64Url = token.split('.')[1]; // 获取载荷部分
  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); // 将 Base64Url 转为 Base64
  const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
    return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  }).join(''));

  return JSON.parse(jsonPayload); // 返回载荷解析后的 JSON 对象
}

function isTokenExpired(token) {
  const payload = parseJwt(token);
  const currentTime = Math.floor(Date.now() / 1000); // 获取当前时间戳(秒)
  return payload.exp < currentTime; // 检查 token 是否过期
}
async function handleRequest(request) {
  const url = new URL(request.url);
  const params = new URLSearchParams(url.search);
  const password = params.get('password');

  if (password !== PASSWORD) {
    return new Response('Unauthorized access', { status: 401 });
  }

  // @ts-ignore
  const token = await oai_global_variables.get('at'); // 这里填入你的 JWT

  if (isTokenExpired(token)) {
    // 如果 Token 过期,执行获取新 Token 的逻辑
    const url = 'https://token.oaifree.com/api/auth/refresh';
    // @ts-ignore
    const refreshToken = await oai_global_variables.get('rt');  // 实际情况下你可能会从某处获取这个值
  
    // 发送 POST 请求
    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
        },
        body: `refresh_token=${refreshToken}`
    });
  
    // 检查响应状态
    if (response.ok) {
        const data = await response.json();
        const token = data.access_token;

        // @ts-ignore
        await oai_global_variables.put('at', token);
    } else {
        return new Response('Error fetching access token', { status: response.status });
    }
  }

  // 如果 Token 未过期,继续执行原来的逻辑
  if (request.method === "POST") {
    const formData = await request.formData();    
    // @ts-ignore
    const at = await oai_global_variables.get('at')
    const access_token = formData.get('access_token') || at; //删除行尾at变量以停止使用内置的access_token(两个竖线也需要删除)
    const unique_name = formData.get('unique_name');
    const site_limit = formData.get('site_limit') || '';
    const expires_in = formData.get('expires_in') || '';
    const gpt35_limit = formData.get('gpt35_limit') || '';
    const gpt4_limit = formData.get('gpt4_limit') || '';
    const show_conversations = formData.get('show_conversations') || 'false';
    const show_userinfo = formData.get('show_userinfo') || 'false';

    const url = 'https://chat.oaifree.com/token/register';
    const body = new URLSearchParams({
      unique_name,
      access_token, // 使用来自表单或KV变量的 access_token
      site_limit,
      expires_in,
      gpt35_limit,
      gpt4_limit,
      show_conversations,
      show_userinfo
    }).toString();

    const apiResponse = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: body
    });

    const responseText = await apiResponse.text();
    const tokenKeyMatch = /"token_key":"([^"]+)"/.exec(responseText);
    const tokenKey = tokenKeyMatch ? tokenKeyMatch[1] : '未找到 Share_token';

    const resultHtml = `
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
      body {
        font-family: Arial, sans-serif;
        background-color: #f4f4f4;
        padding: 20px;
      }
      form, .response-container {
        background: white;
        padding: 20px;
        border-radius: 8px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        max-width: 600px;
        margin: 20px auto;
      }
      label, h1, p {
        display: block;
        margin-bottom: 10px;
        font-size: 16px;
      }
      input[type="text"], input[type="checkbox"], textarea {
        width: calc(100% - 22px);
        padding: 10px;
        margin-top: 5px;
        margin-bottom: 20px;
        border-radius: 5px;
        border: 1px solid #ccc;
      }
      textarea {
        font-family: 'Courier New', monospace;
        background-color: #f8f8f8;
        height: 20px;
      }
      button {
        background-color: #007BFF;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
      }
      button:hover {
        background-color: #0056b3;
      }
      button a {
        color: inherit;
        text-decoration: none;
        background: none;
        padding: 0;
        display: inline;
    }    
      @media (max-width: 768px) {
        body, form, .response-container {
          padding: 10px;
        }
      }
    </style>
    </head>
    <body>
    <div class="response-container">
      <h1>Share Token</h1>
      <textarea id="tokenKey" readonly>${tokenKey}</textarea>
      <button onclick="copyTokenKey()">一键复制</button>
      <button onclick="goToOtherPage2()">享用纯粹ChatGPT Plus</button>
      <script>
        function copyTokenKey() {
          const copyText = document.getElementById("tokenKey");
          copyText.select();
          document.execCommand("copy");
          alert("已复制: " + copyText.value);
        }
        function goToOtherPage2() {
          window.location.href = 'https://${YOUR_DOMAIN}/setcookie.html?access_token=${tokenKey}';
        }
      </script>
      <button><a href="/?password=123">返回</a></button>
    </div>
    </body>
    </html>
    `;

    return new Response(resultHtml, {
      headers: {
        'Content-Type': 'text/html; charset=utf-8'
      },
    });
  } else {
    const formHtml = `
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
      body {
        font-family: Arial, sans-serif;
        background-color: #f4f4f4;
        padding: 20px;
      }
      form {
        background: white;
        padding: 20px;
        border-radius: 8px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        max-width: 600px;
        margin: 20px auto;
      }
      label {
        display: block;
        margin-bottom: 10px;
        font-size: 16px;
      }
      input[type="text"], input[type="checkbox"] {
        width: calc(100% - 22px);
        padding: 10px;
        margin-top: 5px;
        margin-bottom: 20px;
        border-radius: 5px;
        border: 1px solid #ccc;
      }
      button {
        background-color: #007BFF;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
      }
      button:hover {
        background-color: #0056b3;
      }
      @media (max-width: 768px) {
        body {
          padding: 10px;
        }
        form {
          padding: 15px;
        }
      }
    </style>
    </head>
    <body>
    <h1>欢迎使用ChatGPT</h1>
    <form method="POST">
      <label for="unique_name">用户名(必须输入,以区分身份、会话隔离、聊天记录保存。):</label>
      <input type="text" id="unique_name" name="unique_name" placeholder="只能由数字和字母构成" required value="">
      
      <details>
        <summary>更多选项(不懂则无需更改)</summary>
        <br></br>
        <div>
            <label for="access_token">Access Token:<a target="_blank" href="https://token.oaifree.com/auth">获取?</a></label>
            <input type="text" id="access_token" name="access_token" placeholder="your access token" value="">

            <label for="site_limit">Site Limit:</label>
            <input type="text" id="site_limit" name="site_limit" placeholder="All" value="">

            <label for="expires_in">Expires In:</label>
            <input type="text" id="expires_in" name="expires_in" placeholder="以秒为单位,0表示永不过期" value="3600">

            <label for="gpt35_limit">GPT-3.5 Limit:</label>
            <input type="text" id="gpt35_limit" name="gpt35_limit" placeholder="Usage counts, with negative values indicating no limitation" value="-1">

            <label for="gpt4_limit">GPT-4 Limit:</label>
            <input type="text" id="gpt4_limit" name="gpt4_limit" placeholder="Usage counts, with negative values indicating no limitation" value="-1">
        </div>
    </details>
    <br></br>
      <button type="submit">获取你的访问门票 share token</button>
    </form>
    </body>
    </html>
    
    `;

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

顶顶,我发的贴一个看的也没有吗?

3 个赞

我看了

1 个赞

推一个
正在吃可乐果
打字很辛苦的呀

1 个赞

我觉得很快官方就支持了

我觉得也是。

很有用,收藏!

1 个赞

真大佬

敬佩大佬

大佬太强了

收藏了

搞七捻三软件开发

小白有点不懂,这个YOUR_DOMAIN是要自己买个域名吗

可以买,也可以用worker的域名。不想反代new站的话直接用始皇new.oaifree.com域名即可

1 个赞

问下佬这样访问https://new.oaifree.com/setcookie.html?access_token=xxx为啥是404啊

你不能访问new站这个接口因为new没有这个接口,你需要使用workers反代new站,同时增加setcookie接口,代码在开头已经给出。
ps.看看我的【接力,小白向教程】兄弟们,Share token使用更更更更优雅了!

跟大佬学习了。

用在nginx,用宝塔测试成功

location /go.htm {
        if ($arg_access_token != "") {
        add_header Set-Cookie "access_token=$arg_access_token; Path=/; Secure; HttpOnly";
        return 302 /; 
    }
}

location / {
    proxy_pass https://new.oaifree.com;
    proxy_set_header Host new.oaifree.com;
    proxy_buffering off;
    proxy_ssl_server_name on;
    proxy_set_header Cookie $http_cookie;
}
1 个赞

大佬

mark下

始皇疑似刚更新了代码,原来直接设置access_token的方式不行了
我稍微改了一下代码,目前测试下来没什么问题

2 个赞