那就没得问题啊
1 个赞
不知道哪里的问题了 照着我的设置搞吧
我把KV在前面定义看看
1 个赞
kv里的at必须设置为空或者取到的accesstoken
老哥解决了没,我刚刚试了一下,发现和你这一样的问题,进入之后一样会出现error
我也是进入后有问题
上面都是正常的 按我说的设置就好了
忽略就行
1 个赞
可以试试我的,改进了一点密码错误处理机制,支持2个账号设置(可自行添加)。:
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 对象
}
async function getOAuthLink(shareToken, YOUR_DOMAIN) {
const url = `https://${YOUR_DOMAIN}/api/auth/oauth_token`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Origin': `https://${YOUR_DOMAIN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
share_token: shareToken
})
})
const data = await response.json();
return data.login_url;
}
function isTokenExpired(token) {
const payload = parseJwt(token);
const currentTime = Math.floor(Date.now() / 1000); // 获取当前时间戳(秒)
return payload.exp < currentTime; // 检查 token 是否过期
}
async function handleRequest(request) {
const requestURL = new URL(request.url);
const path = requestURL.pathname;
// 检查路径是否匹配 "/auth/login_auth0"
if (path !== "/auth/login_auth0") {
requestURL.host = "new.oaifree.com";
return fetch(new Request(requestURL, request));
}
// 这里填入你的 JWT
// 如果 Token 未过期,继续执行原来的逻辑
if (request.method === "POST") {
const formData = await request.formData();
const accountChoice = formData.get("account_choice");
// 根据选择获取对应的 access_token
// @ts-ignore
const token = accountChoice === '1' ? await oai_global_variables.get("at1") : await oai_global_variables.get("at2");
// @ts-ignore
const SITE_PASSWORD =
// @ts-ignore
(await oai_global_variables.get("SITE_PASSWORD")) || "";
const site_password = formData.get("site_password") || "";
if (site_password !== SITE_PASSWORD) {
const uniqueName = formData.get("unique_name") || ""; // 获取表单中的昵称值
const accountChoice = formData.get("account_choice") || "1"; // 获取表单中的账号选择,缺省值为"1"
const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.input-wrapper select {
width: 320px; /* 和其他 input 元素保持一致 */
height: 52px; /* 调整高度以匹配设计 */
padding: 10px; /* 适当的内边距以美化视觉效果 */
border-radius: 5px; /* 圆角与输入框保持一致 */
border: 1px solid #ccc; /* 初始边框颜色 */
background-color: #ffffff; /* 背景色 */
font-size: 16px; /* 字体大小与其他输入框一致 */
color: red; /* 字体颜色,以提高可读性 */
outline: none; /* 去除默认轮廓 */
-webkit-appearance: none; /* 删除iOS默认样式 */
-moz-appearance: none; /* 删除Firefox默认样式 */
appearance: none; /* 删除默认样式 */
}
.input-wrapper select:focus {
border-color: #0f9977; /* 聚焦时的边框颜色 */
}
.input-wrapper select:hover {
border-color: #0f9977; /* 悬停时的边框颜色 */
}
.input-wrapper label {
position: absolute;
left: 10px;
top: -10px; /* 调整标签位置,使其在动画开始时就位 */
transition: top 0.3s, font-size 0.3s, color 0.3s;
color: #ccc;
background-color: #ffffff;
padding: 0 5px; /* 标签的内边距防止背景与边框重叠 */
}
.input-wrapper select:not(:placeholder-shown) + label,
.input-wrapper select:focus + label {
top: -20px; /* 向上移动标签 */
font-size: 12px; /* 缩小字体 */
color: #0f9977; /* 改变颜色 */
}
.title {
font-size: 32px;
font: "Söhne";
color: #2d333a;
width: 320px;
text-align: center;
}
.oai-header {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
background-color: #fff;
}
header {
unicode-bidi: isolate;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 90vh;
overflow: hidden;
}
h1{
text-align: center;
}
input{
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
outline: none;
}
.input-wrapper {
position: relative;
margin-bottom: 20px;
}
.input-wrapper label {
position: absolute;
left: 10px;
top: 14px;
transition: 0.3s;
color: #ccc;
background-color: #ffffff;
}
.input-wrapper input {
width: 298.4px;
height: 50.4px;
padding: 0 10px;
border-radius: 5px;
border: 1px solid #ccc;
display: block;
font-size: 16px;
}
.input-wrapper input:not(:placeholder-shown) {
border-color: #0f9977 !important;
}
.input-wrapper input:focus {
border-color: #0f9977 !important;
}
.input-wrapper input:focus + label,
.input-wrapper input:not(:placeholder-shown) + label {
top: -10px;
left: 10px;
font-size: 16px;
color: #0f9977;
}
button {
background-color: #0f9977;
color: #ffffff;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
width: 320px !important;
height: 52px;
}
@media (max-width: 768px) {
body,
form,
.response-container {
padding: 20px;
}
}
</style>
</head>
<body>
<div>
<header class="oai-header" data-immersive-translate-walked="a50a507b-b686-4aff-b614-6c58864d5cec"><img src="https://img2.imgtp.com/2024/04/20/z9twuEmo.svg" alt="OpenAI's Logo"></header>
<h1 class="title" data-immersive-translate-walked="a50a507b-b686-4aff-b614-6c58864d5cec">欢迎回来</h1>
<form method="POST">
<div class="input-wrapper">
<select id="account_choice" name="account_choice" required>
<option value="1" ${accountChoice === '1' ? 'selected' : ''}>ChatGPT Team账号1</option>
<option value="2" ${accountChoice === '2' ? 'selected' : ''}>ChatGPT Team账号2</option>
</select>
</div>
<div class="input-wrapper">
<input type="text" id="unique_name" name="unique_name" placeholder=" " required value="${uniqueName}">
<label for="unique_name">请输入一个独一无二的昵称</label>
</div>
<div class="input-wrapper">
<input type="password" id="site_password" name="site_password" placeholder=" " required>
<label for="site_password">请输入正确的访问密码</label>
<span id="error-message" style="color: red; display: none;">访问密码错误</span>
</div>
<button type="submit">继续</button>
</form>
<script>
document.getElementById('error-message').style.display = 'inline'; // 显示错误消息
setTimeout(() => {
document.getElementById('error-message').style.display = 'none'; // 2秒后隐藏错误消息
}, 2000);
document.getElementById('site_password').focus(); // 自动聚焦到密码输入框
document.addEventListener('DOMContentLoaded', function () {
var selectElement = document.getElementById('account_choice');
var labelElement = document.querySelector('label[for="account_choice"]');
selectElement.addEventListener('change', function() {
var selectedOption = selectElement.options[selectElement.selectedIndex].text;
labelElement.textContent = selectedOption; // 更新标签文本为选中的选项
});
});
</script>
</body>
</html>
`;
return new Response(htmlContent, {
status: 401,
headers: { "Content-Type": "text/html" },
});
}
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(accountChoice === '1' ? "at1" : "at2", token);
} else {
return new Response("Error fetching access token", {
status: response.status,
});
}
}
// @ts-ignore
const access_token = token;
const unique_name = formData.get("unique_name");
const site_limit = "";
const expires_in = "0";
const gpt35_limit = "-1";
const gpt4_limit = "-1";
const show_conversations = "false";
const reset_limit = "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,
reset_limit,
}).toString();
const apiResponse = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: body,
});
const respJson = await apiResponse.json();
const tokenKey =
"token_key" in respJson ? respJson.token_key : "未找到 Share_token";
// @ts-ignore
const YOUR_DOMAIN = await oai_global_variables.get('YOUR_DOMAIN') || requestURL.host;
return Response.redirect(`https://${YOUR_DOMAIN}/auth/login_share?token=${tokenKey}`, 301)
}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>
.input-wrapper select {
width: 320px; /* 和其他 input 元素保持一致 */
height: 52px; /* 调整高度以匹配设计 */
padding: 10px; /* 适当的内边距以美化视觉效果 */
border-radius: 5px; /* 圆角与输入框保持一致 */
border: 1px solid #ccc; /* 初始边框颜色 */
background-color: #ffffff; /* 背景色 */
font-size: 16px; /* 字体大小与其他输入框一致 */
color: red; /* 字体颜色,以提高可读性 */
outline: none; /* 去除默认轮廓 */
-webkit-appearance: none; /* 删除iOS默认样式 */
-moz-appearance: none; /* 删除Firefox默认样式 */
appearance: none; /* 删除默认样式 */
}
.input-wrapper select:focus {
border-color: #0f9977; /* 聚焦时的边框颜色 */
}
.input-wrapper select:hover {
border-color: #0f9977; /* 悬停时的边框颜色 */
}
.input-wrapper label {
position: absolute;
left: 10px;
top: -10px; /* 调整标签位置,使其在动画开始时就位 */
transition: top 0.3s, font-size 0.3s, color 0.3s;
color: #ccc;
background-color: #ffffff;
padding: 0 5px; /* 标签的内边距防止背景与边框重叠 */
}
.input-wrapper select:not(:placeholder-shown) + label,
.input-wrapper select:focus + label {
top: -20px; /* 向上移动标签 */
font-size: 12px; /* 缩小字体 */
color: #0f9977; /* 改变颜色 */
}
.title {
font-size: 32px;
font: "Söhne";
color: #2d333a;
width: 320px;
text-align: center;
}
.oai-header {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
background-color: #fff;
}
header {
unicode-bidi: isolate;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 90vh;
overflow: hidden;
}
h1{
text-align: center;
}
input{
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
outline: none;
}
.input-wrapper {
position: relative;
margin-bottom: 20px;
}
.input-wrapper label {
position: absolute;
left: 10px;
top: 14px;
transition: 0.3s;
color: #ccc;
background-color: #ffffff;
}
.input-wrapper input {
width: 298.4px;
height: 50.4px;
padding: 0 10px;
border-radius: 5px;
border: 1px solid #ccc;
display: block;
font-size: 16px;
}
.input-wrapper input:not(:placeholder-shown) {
border-color: #0f9977 !important;
}
.input-wrapper input:focus {
border-color: #0f9977 !important;
}
.input-wrapper input:focus + label,
.input-wrapper input:not(:placeholder-shown) + label {
top: -10px;
left: 10px;
font-size: 16px;
color: #0f9977;
}
button {
background-color: #0f9977;
color: #ffffff;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
width: 320px !important;
height: 52px;
}
@media (max-width: 768px) {
body,
form,
.response-container {
padding: 20px;
}
}
</style>
</head>
<body>
<div>
<header class="oai-header" data-immersive-translate-walked="a50a507b-b686-4aff-b614-6c58864d5cec"><img src="https://img2.imgtp.com/2024/04/20/z9twuEmo.svg" alt="OpenAI's Logo"></header>
<h1 class="title" data-immersive-translate-walked="a50a507b-b686-4aff-b614-6c58864d5cec">欢迎回来</h1>
<form method="POST">
<div class="input-wrapper">
<select id="account_choice" name="account_choice" required>
<option value="1">ChatGPT Team账号1</option>
<option value="2">ChatGPT Team账号2</option>
</select>
</div>
<div class="input-wrapper">
<input type="text" id="unique_name" name="unique_name" placeholder=" " required value="">
<label for="unique_name">请输入一个独一无二的昵称</label>
</div>
<div class="input-wrapper">
<input type="password" id="site_password" name="site_password" placeholder=" ">
<label for="site_password">请输入正确的访问密码</label>
</div>
<button type="submit">继续</button>
</form>
<script>
document.addEventListener('DOMContentLoaded', function () {
var selectElement = document.getElementById('account_choice');
var labelElement = document.querySelector('label[for="account_choice"]');
selectElement.addEventListener('change', function() {
var selectedOption = selectElement.options[selectElement.selectedIndex].text;
labelElement.textContent = selectedOption; // 更新标签文本为选中的选项
});
});
</script>
</div>
</body>
</html>
`;
return new Response(formHtml, {
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
}
}
YOUR_DOMAIN可以填自己的域名在这里设置
这里链接kv数据库
效果如图:
2 个赞
不错 赞
,感谢,新玩意儿也不错
kv怎么设置的
1 个赞
浏览上面的之后,我kv设置的是和他们一样的,就是your。domain设置成了自己的,也绑定了,代码里面我不大懂,也没敢改。(额,就是那个是反代,我看了好多之后,填入的是已经反代好的new.oaifree.com)
原本自己的域名不用反代了 代码里有反代操作
1 个赞