- AI 应用
- 提示工程
- 人工智能
- 前端
【免费下载链接】ChatGPT-Shortcut
Stop writing prompts from scratch — a searchable prompt library for ChatGPT, Claude, Gemini and Cursor · Русский 한국어 العربية हिन्दी ไทย | 别再从头写提示词:现成的拿来就用,好用的收进自己的库
ChatGPT-Shortcut(AiShort)是一个可搜索的提示词库,支持 ChatGPT、Claude、Gemini 与 Cursor 等多个 AI 工具。它允许匿名使用,但只有登录后才能收藏提示词、创建自定义提示词、分享到社区并在多台设备间同步「我的收藏」。本文基于仓库中的账户指南文档(i18n/de/docusaurus-plugin-content-docs/current/guides/account.md)与对应前端源码,完整讲解三种登录方式、注册流程、「我的账户」页面的个人资料与密码管理、L0–L9 等级体系,以及数据导出/导入/缓存清除的实现细节,帮助读者既会用这些功能,又理解它们背后的 API 调用链与本地缓存机制。
为什么账号是可选的
站点本身是无账号可用的:浏览提示词、搜索、复制提示词都不需要登录。登录的价值在于:
- 收藏精选提示词与社区提示词到「我的收藏」;
- 创建、编辑、删除自己的自定义提示词(可公开分享或设为私密);
- 将上述数据按账户存储,实现跨设备、跨浏览器同步。
从前端结构看,整个身份体系围绕 src/components/AuthContext.tsx 展开:登录成功后 JWT 写入localStorage的auth_token,AuthProvider 再拉取/myspace等用户数据并维护全局状态;页面组件(收藏视图、用户中心)都从该 Context 读取。
三种登录方式
登录对话框提供「密码登录」和「免密登录」两个 Tab,外加一键 Google 登录。在 src/components/user/login.tsx 中,对话框通过viewState(login/register/forgot-password)和loginType(password/code)两个状态切换不同表单视图,所有请求最终汇聚到 src/api/auth.ts 导出的接口函数。
密码登录
使用用户名或注册邮箱 + 密码登录。对应源码为login():
export async function login(values: { username: string; password: string }) { const response = await apiClient.post(`/auth/local`, { identifier: values.username, password: values.password, }); clearUserCachesOnLogin(); // 清除旧用户的 USER_PROFILE 与 MySpace 缓存 return response; }两个实现细节值得注意:
- identifier 即用户名或邮箱——接口不区分二者,用户填哪个后端都能识别,这与 UI 中「用户名/邮箱」的占位符提示一致;
- 登录后先清缓存——
clearUserCachesOnLogin()会同时清掉USER_PROFILE与MySpace两块本地缓存,防止上一个账号的残留 ETag 与新账号巧合命中(源码注释明确指出这是为避免旧账号数据串到新账号)。
登录成功后 src/components/user/login.tsx 中的handleSuccess会:把 JWT 存入localStorage("auth_token"),通过window.postMessage向浏览器扩展页发送{ action: "login", username, jwt }消息(让浏览器扩展也能感知登录状态),然后刷新页面。
免密登录(登录链接)
适合「只是偶尔登录一次」的用户,无需记忆密码:
- 切到「免密登录」Tab,输入注册邮箱(或用户名);
- 点击「获取登录链接」,系统向你的邮箱发送一条登录链接;
- 点击邮件中的链接完成登录。
源码上有两点比文档更细:
- 前端 src/components/user/login.tsx 的
handleSendPasswordlessLink会用正则/\S+@\S+\.\S+/判断输入是否为邮箱格式:是邮箱就发{ email },不是就发{ username },所以用户名同样能收到登录链接; - 接口分两步:
sendPasswordlessLink()向POST /passwordless/send-link发请求取链接;用户点击邮件中的链接后,页面携带loginToken调loginWithToken()执行GET /passwordless/login?loginToken=...,拿回jwt后同样执行persistAuthToken+ 清缓存,与密码登录走同一条状态落地路径。
Google 一键登录
在登录对话框点击「Login via Google」即可;首次通过 Google 登录时系统会自动为你创建账户,无需单独注册。
从 src/api/auth.ts 的实现看,Google 登录是一个完整的 OAuth 重定向流程,且由USE_LEGACY_GAUTH开关(见 src/api/config.ts)在两套后端流程间切换:
| 配置 | 流程 |
|---|---|
USE_LEGACY_GAUTH = false(当前默认) | 前端拼接${GAUTH_API_BASE}/api/connect/google?redirect=<origin>/user/auth,由 Strapi 原生 OAuth 路由接管,回调时把jwt与user带回前端 |
USE_LEGACY_GAUTH = true(旧版) | 先请求/strapi-google-auth/init获取跳转 URL;授权后用code调/strapi-google-auth/user-profile换取 token,再调/me拉取用户信息 |
关键常量与路径(均来自 src/api/config.ts 与 src/api/auth.ts):
export const API_URL = "https://api.newzone.top/api"; // 主 API(Strapi 后端) export const GAUTH_API_BASE = "https://gauth.aishort.top"; // Google OAuth 入口服务 export const USE_LEGACY_GAUTH = false;配置注释解释了为什么需要独立的gauth服务:主服务器所在网络无法直连 Google,因此 OAuth 入口被拆到独立域名。前端侧,handleGoogleLogin会打开一个 520×570 的弹出窗口展示加载动画,跳转到认证 URL;授权完成后window的message事件监听器捕获回传的jwt/access_token/code等载荷,调用googleLogin()完成认证。若弹窗被浏览器拦截,会提示「Pop-up window blocked」。
登录态的本地校验
JWT 并非「存了就算数」。src/components/AuthContext.tsx 中的isValidToken会在本地解码 JWT 的payload.exp并与当前时间比较(预留 60 秒时钟偏差余量):过期的 token 会被直接删除并视为未登录,避免拿着失效凭证反复请求后端;解析失败时则保守地认为有效,防止误登出。此外 AuthProvider 采用 stale-while-revalidate 策略——刷新页面时先用本地缓存的user_auth立即渲染,避免登录状态「闪烁」。
注册账户
- 在登录对话框点击「立即注册」切到注册视图;
- 填写用户名、邮箱、密码,并勾选同意服务条款与隐私政策;
- 提交后自动完成登录。
表单校验规则(src/components/user/login.tsx 顶部的rules)给出了具体约束:
- 用户名必填;
- 密码必填且至少 6 个字符;
- 邮箱必填且需通过邮箱格式校验;
- 注册必须勾选同意框,否则报错「使用前须同意服务条款和隐私政策」。
注册请求由 src/api/auth.ts 的register()发出:POST /auth/local/register,载荷为{ username, email, password }。与密码登录复用同一个handleAuth成功处理器——返回的jwt落盘、postMessage通知扩展、500ms 后刷新页面,所以注册完即处于登录态。
我的账户页面
登录后进入「我的账户」页(src/pages/user/index.tsx),页面未加载到用户信息时会在 2 秒后自动跳回首页(即未登录访问会重定向)。页面分为三块:用户信息、安全设置、数据管理。
修改用户名
点击用户名旁的编辑图标,输入新用户名并点保存。源码对应submitNewUsername:调用 src/api/user.ts 的updateUsername(),即PUT /favorites/update-username,载荷{ newUsername };成功后重新拉取用户信息刷新页面。接口名带favorites前缀,可以推断后端把「显示名」归在收藏/社区可见性相关的控制器里管理,改名会同步影响该用户提示词在社区的展示。
修改密码与忘记密码
修改密码三步:填写当前密码 → 填写并确认新密码 → 点「修改密码」,对应 src/api/auth.ts 的changePassword():POST /auth/change-password,载荷为{ currentPassword, newPassword, confirmPassword }(其中新密码以password与passwordConfirmation两个字段提交)。
这里有一个源码中才能发现的细节:src/pages/user/index.tsx 中「当前密码」输入框只在userInfo?.provider === "local"时渲染。也就是说,通过 Google 登录的账户(provider 不是 local)修改密码时无需填写当前密码,只需设置新密码——这也意味着 Google 账户可以「补一个密码」,之后即可用密码登录。
忘记密码有两条入口:登录对话框的「忘记密码」,以及「我的账户 → 安全设置」右上角的「忘记密码」按钮。两者都调用 src/api/auth.ts 的forgotPassword()(POST /auth/forgot-password)向注册邮箱发送重置邮件,然后点击邮件中的链接,由 src/pages/reset-password.tsx 页面处理最终重置,对应resetPassword():POST /auth/reset-password,载荷{ code, newPassword, confirmPassword },其中code来自邮件链接。
等级体系:L0–L9
账户页会展示你的Level(L0–L9)与升到下一级的进度。等级由你分享到社区的提示词数量决定——注意统计的是share为真的自定义提示词(src/pages/user/index.tsx 中userprompts.filter((p) => p.share).length),收藏数、浏览数都不计入。
具体阈值曲线定义在 src/components/LevelSystem.tsx:
export const LEVEL_THRESHOLDS = [0, 1, 3, 8, 18, 35, 60, 100, 160, 260];| 等级 | 名称 | 所需分享提示词数 |
|---|---|---|
| L0 | 萌新探索者 | 0 |
| L1 | 青铜 | ≥ 1 |
| L2 | 白银 | ≥ 3 |
| L3 | 黄金 | ≥ 8 |
| L4 | 铂金 | ≥ 18 |
| L5 | 钻石 | ≥ 35 |
| L6 | 蓝宝石 | ≥ 60 |
| L7 | 红宝石 | ≥ 100 |
| L8 | 翡翠 | ≥ 160 |
| L9 | 星辉 | ≥ 260 |
相邻等级跨距依次为 1、2、5、10、17、25、40、60、100,约 1.6–2 倍递增,曲线平滑;L9 被定位为「传奇」档。页面显示的进度百分比为min(100, sharedCount / next * 100);达到 L9 后显示「MAX REACHED」。等级图标是一组随等级累积几何元素的 SVG 多边形(src/components/LevelSystem.tsx 的LevelIcon),L7 加中心圆点、L8 加粗描边、L9 加 8 条辐射线,纯 stroke 绘制、跨平台不依赖 emoji 字体。
数据管理
「我的账户 → 数据管理」提供三个操作:清除缓存、导出提示词、导入提示词。
清除缓存
点击「清除所有缓存」(带二次确认弹窗)会执行 src/pages/user/index.tsx 的handleClearCache:
clearUserProfileCache(); // 清除 USER_PROFILE 缓存 clearMySpaceCache(); // 清除 MYSPACE 缓存 await fetchUserInfo(); // 重新拉取用户数据它只刷新本地缓存,不会删除任何服务端数据:收藏与自定义提示词都保存在账户里,清缓存只是丢弃浏览器里的旧副本并重新同步。文档建议的使用场景正是「数据不同步或显示异常」时的第一步自救——因为前端大量使用 ETag + TTL 缓存(见 src/api/user.ts 中getUserAllInfo对If-None-Match/ 304 的处理),偶发不一致时清缓存可强制重新协商。
导出提示词
点「导出数据」生成一个 JSON 文件并自动下载,文件名形如my-prompts-2026-09-24.json(当天日期)。src/pages/user/index.tsx 的handleExportPrompts会先批量拉取自定义提示词、收藏的精选卡(cards)与社区提示词(commus)的完整数据,再组装导出结构:
{ "exportTime": "ISO8601 时间戳", "prompts": [ // 全部自定义提示词 { "id": 1, "title": "…", "prompt": "…", "remark": "…", "notes": "…", "share": true } ], "favorites": { "card": [3, 7], "community": [12] }, // 收藏 ID 列表(导入用) "favoriteDetails": [ /* 收藏的详细内容,仅供人工查看,导入时忽略 */ ], "myspaceOrder": [ /* MySpace 卡片顺序,type/source/id 三元组 */ ], "customTags": [ /* 自定义标签定义 */ ] }字段含义上值得注意:prompts里prompt字段对应后端存储的description,share表示该提示词是否已分享到社区;favoriteDetails与myspaceOrder、customTags是备份性质的快照,当前联网版导入时不会用它们恢复排序与标签(源码注释解释了原因:排序/标签中的 ID 属于源用户,覆盖式写入会破坏目标用户已有的体系)。
导入提示词
选择 JSON 文件导入,handleImportPrompts的实现比文档描述复杂得多,兼容三种输入格式:
- 纯数组:
[ { title, prompt, … } ]; - 对象:
{ prompts: [...], favorites: { card: [], community: [] } }(即导出文件本身); - 单个提示词对象:
{ title, prompt|description }。
规范化时以prompt || description作为正文,过滤掉缺title或缺正文的条目。冲突处理策略分四种情形:
| 情形 | 行为 |
|---|---|
有id且属于当前用户,内容与现有完全一致 | 跳过(skipped) |
有id且属于当前用户,内容有差异 | 按id更新该提示词 |
无id | 新建,share默认取文件值,缺省为公开(true) |
有id但不属于当前用户 | 作为新的私密提示词创建(share: false),防止误覆盖他人数据 |
收藏导入采用增量合并:只把本地不存在的favorites.card/favorites.communityID 通过PATCH /favorites(loves.add/commLoves.add)合并进现有收藏,不做删除,且服务端按 merge 语义处理以保证多设备并发安全。全部任务用Promise.allSettled并发执行,完成后汇总「成功 / 跳过 / 失败」数量并给出「全部成功」「部分导入成功 (x/y)」「导入失败」三档提示,最后调用refreshUserAuth()刷新 MySpace 视图。
小结:账户数据流全景
把本文涉及的端点串起来,AiShort 账户体系的完整调用链为:
- 认证:
POST /auth/local/register(注册)、POST /auth/local(密码登录)、POST /passwordless/send-link+GET /passwordless/login(免密)、GET /api/connect/google(OAuth)、POST /auth/change-password、POST /auth/forgot-password+POST /auth/reset-password; - 账户数据:
GET /users/me(ETag 缓存)、PUT /favorites/update-username(改名)、GET /myspace(收藏 + 自定义提示词聚合); - 前端职责:JWT 本地过期校验、Stale-While-Revalidate 缓存、登录后强制清缓存、乐观更新 + 失败回滚。
所有认证请求集中封装在 src/api/auth.ts,端点基址集中在 src/api/config.ts,便于整体替换后端;页面层则分别是 src/components/user/login.tsx(登录/注册/忘记密码对话框)与 src/pages/user/index.tsx(我的账户)。
相关文档
- 入门指南:基本使用方法
- 我的收藏:收藏与自定义标签管理
- 自定义提示词:创建、编辑、分享与导出提示词
- AI 应用
- 提示工程
- 人工智能
- 前端
【免费下载链接】ChatGPT-Shortcut
Stop writing prompts from scratch — a searchable prompt library for ChatGPT, Claude, Gemini and Cursor · Русский 한국어 العربية हिन्दी ไทย | 别再从头写提示词:现成的拿来就用,好用的收进自己的库
相关推荐
Meteor 用户与账户系统完全指南:密码登录、无密码登录、2FA 与 OAuth 集成实战
Meteor 用户与账户系统完全指南:密码登录、无密码登录、2FA 与 OAuth 集成实战 导读 :本文以 Meteor 官方教程 Users and Acc
后端前端开发工具移动开发docker-mailserver 的 Dovecot Master Accounts(主账户)详解:跨账户管理登录与热备份实践
docker mailserver 的 Dovecot Master Accounts(主账户)详解:跨账户管理登录与热备份实践 导读 本文围绕 docker
后端通信云原生downkyi账户登录记录查看:检查账号的登录历史
downkyi账户登录记录查看:检查账号的登录历史 一、登录记录审计的安全价值 B站用户账号面临的登录风险呈现三大特征: | 风险类型 | 技术原理 | 检测难
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考