【优雅+安全】GPT4私人拼车神器——轻松实现聊天隔离+链接直达+全自动刷新token

不懂,但膜拜

1 个赞

很奇怪,最近试了,一直提示token获取失败,我log下了日志,ac都是正常显示出来的。然后,还有个bug,并不能刷新ac,每次都要手动上传ac

我因为之前没rt还没试过自动刷新,现在有rt了,等我试试看

1 个赞

感谢分享

好东西,感谢佬!

期待一波。

厉害的佬

rt刷新at的部分可以参考我贴的部分代码。

2 个赞

代码已经更新啦,顺便做了一些结构上的改动:

高级啊,虽然我不懂

厉害,回家去试试

mark

mark: gpt优雅拼车

马克

1 个赞

大佬,这里你先前的,今天直接抛异常了,劳烦你佬看下:

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 getOAuthLink(shareToken, proxiedDomain) {
const url = https://${proxiedDomain}/api/auth/oauth_token;
const response = await fetch(url, {
method: ‘POST’,
headers: {
‘Origin’: https://${proxiedDomain},
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify({
share_token: shareToken
})
})
const data = await response.json();

return data.login_url;
}

async function getShareToken(userName, at) {
const url = ‘https://chat.oaifree.com/token/register’;
const body = new URLSearchParams({
// 此处为获取Share Token时的请求参数,可自行配置
access_token: at,
unique_name: userName,
site_limit: ‘’, // 限制的网站
expires_in: ‘0’, // token有效期(单位为秒),填 0 则永久有效
gpt35_limit: ‘-1’, // gpt3.5 对话限制
gpt4_limit: ‘-1’, // gpt4 对话限制
show_conversations: ‘false’, // 是否显示所有人的会话
show_userinfo: ‘false’, // 是否显示用户信息
reset_limit: ‘false’ // 是否重置对话限制
}).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 获取失败’;
return tokenKey;
}

async function handleRequest(request) {
const url = new URL(request.url);
const params = new URLSearchParams(url.search);
const userName = params.get(‘un’);
if (!userName) {
// 如果没有 ‘un’ 参数,返回 HTML 表单
return new Response(formHtml, {
headers: {
‘Content-Type’: ‘text/html; charset=utf-8’
}
});
}

// @ts-ignore
// 验证用户名是否存在
const users = await oai_global_variables.get(“users”);
if (!users.split(“,”).includes(userName)) {
return new Response(‘用户不存在’, { status: 404 });
}

// @ts-ignore
const accessToken = await oai_global_variables.get(‘at’);
if (isTokenExpired(accessToken)) {
// 给没有refresh token的萌新用(比如我),取消下面这行注释即可享用
// return new Response(‘当前access token未更新,请联系管理员更新’, { status: 401 });

  // 如果 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();  // 假设服务器返回的是 JSON 格式数据
      // @ts-ignore
      accessToken = data.access_token;; // 直接从 JSON 中获取 access_token

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

}
// @ts-ignore
//const tokenPrefix = await oai_global_variables.get(‘token_prefix’);

const shareToken = await getShareToken(userName, accessToken);
if (shareToken === ‘share token 获取失败’) {
return new Response(‘token获取失败,请刷新重试’, { status: 500 });
}

// @ts-ignore
const proxiedDomain = await oai_global_variables.get(‘proxied_domain’);
return Response.redirect(await getOAuthLink(shareToken, proxiedDomain), 302);
}
// HTML 表单代码
const formHtml = `

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; } h1 { text-align: center; } h2 { text-align: center; } p { display: block; margin-bottom: 10px; font-size: 16px; } input[type="text"], 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: 150px; /* Adjust height based on your needs */ } button { background-color: #000000; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; font-weight:600; width:100% !important } button:hover { background-color: #1e293b; } @media (max-width: 768px) { body, form, .response-container { padding: 10px; } } .checkbox-group { display: flex; justify-content: space-between; } .checkbox-group input[type="checkbox"] { margin-right: 5px; } .checkbox-group label { margin-right: 10px; }

欢迎使用ChatGPT

请输入独一无二的名字,以你的区分身份,用于会话隔离:

访问使用 `;

异常显示:

throw new DOMException(
‘Too late to call FetchEvent.respondWith(). It must be called synchronously in the event handler.’,
‘InvalidStateError’
);
}
this.stopImmediatePropagation();
这里:

Error 1101 Ray ID: 88d5b3ad0dd7b441 • 2024-06-02 07:24:08 UTC

Worker threw exception

50个3.5普号:https://free.chatpro.icu

有点没看懂你的格式()
你这个好像不是我的最新版本,换新的试试,我在上面有回复链接

之前的pandora,现在没了

网页提示:token获取失败,请刷新重试

这两天出问题了佬,求救,谢谢!(at rt确认都正确,始皇官网都正常用)

用的代码版本是这个帖子版的还是新版的呀?

这个帖的有点问题,但编辑不了,已经更新到新帖子了