打造属于你的云端书签管理器:构建 Hugo + Cloudflare 网站与 Chrome 同步扩展和管理员登录
在这个数据为王的时代,拥有一个属于自己的不受平台限制的个人数据中心,是一件非常有成就感的事情。今天,我们将从零开始,亲手打造一个强大快速且几乎零成本的个人书签管理器。
这个项目不仅是一个简单的网页,它是一个完整的生态系统:一个由 Hugo 构建的闪电般快速的前端网站,一个由 Cloudflare Functions 和 D1 数据库驱动的强大后端,以及一个能实现浏览器书签自动同步的 Chrome 扩展。
第一部分:构建云端书签网站
我们的目标是创建一个功能齐全的网站,可以让我们对书签进行增删改查分类导入/导出等所有操作。
第一步:项目规划与技术选型
我们选择一套现代高效且免费的“黄金组合”:
- 前端框架 (Hugo):一个用 Go 语言编写的静态网站生成器,以其惊人的构建速度而闻名。它将为我们生成一个轻量快速的网站骨架。
- 部署与后端平台 (Cloudflare Pages):一个集静态托管Serverless 函数(Functions)和数据库(D1)于一体的强大平台。它的免费额度足以支撑绝大多数个人项目。
- 数据库 (Cloudflare D1):Cloudflare 的无服务器 SQL 数据库,与 Pages Functions 无缝集成,简单易用。
- UI 样式 (Pico.css):一个极简的 CSS 框架,只需引入一个文件,就能让我们的应用看起来专业美观。
第二步:环境准备与项目初始化
-
安装 Hugo: 确保你的电脑上已经安装了 Hugo。
-
创建项目:
hugo new site my-bookmark-app cd my-bookmark-app
-
建立项目结构: 在项目根目录,我们创建
functions
和d1
文件夹,并规划出如下结构,确保static
文件夹和hugo.toml
配置文件都已就位。my-bookmark-app/ │ hugo.toml # Hugo 配置文件 │ wrangler.toml # Cloudflare 配置文件 │ ├─content/ │ _index.md ├─d1/ │ └─migrations/ │ 0001_create_bookmarks.sql # 数据库结构 ├─functions/ │ └─api/ │ └─[[catchall]].js # 后端 API ├─layouts/ │ index.html # 网站主模板 └─static/ ├─css/ │ style.css └─js/ app.js
第三步:数据库设计 (d1/migrations
)
我们定义书签表 bookmarks
的结构。这个 SQL 文件不仅定义了表,还插入了一些初始数据方便测试。
-- 0001_create_bookmarks.sql
CREATE TABLE bookmarks (
id INTEGER PRIMARY KEY AUTOINCREMENT
name TEXT NOT NULL
url TEXT NOT NULL
category TEXT DEFAULT '未分类'
tags TEXT
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)
-- 插入一些示例数据
INSERT INTO bookmarks (name url category tags) VALUES
('Cloudflare D1 官方文档' 'https://developers.cloudflare.com/d1/' '技术文档' 'CloudflareD1')
('Hugo 官方文档' 'https://gohugo.io/documentation/' '技术文档' 'HugoStatic')
第四步:后端 API 开发 (functions/api
)
这是应用的大脑。[[catchall]].js
文件会处理所有 /api/*
的请求,像一个迷你的 API 服务器。它负责连接 D1 数据库,并提供以下核心接口:
GET /api/bookmarks
:获取所有书签,支持搜索和分类。POST /api/bookmarks
:添加一个新书签。PUT /api/bookmarks/:id
:修改一个已存在的书签(比如修改分类)。DELETE /api/bookmarks/:id
:删除一个书签。GET /api/categories
:获取所有分类及其数量。DELETE /api/categories/:name
:删除一个分类及其下的所有书签。POST /api/bookmarks/import
:批量导入书签。POST /api/bookmarks/exists
:检查一组 URL 是否已存在。
第五步:前端界面构建 (layouts
和 static
)
layouts/index.html
: 这是网站的 HTML 骨架,包含了添加表单书签列表数据管理等所有 UI 元素的布局。static/css/style.css
: 我们在这里编写自定义样式,利用 CSS Grid 实现多列响应式布局,并美化各种元素。static/js/app.js
: 这是前端的交互核心。它负责:- 页面加载时,调用 API 获取并渲染书签和分类列表。
- 处理表单提交删除修改分类等用户操作。
- 实现导入/导出逻辑,包括解析 HTML 文件和生成浏览器兼容的 HTML 文件。
- (可选)处理思维导图的生成与交互。
第六步:本地开发与部署
本地开发工作流 (我们最终确定的最佳实践):
- 修改代码: 编辑
layouts
static
或functions
里的文件。 - 构建前端: 每当修改了前端文件后,运行
hugo --minify
来生成一个干净的不含开发脚本的public
文件夹。 - 启动本地服务: 运行
wrangler pages dev public
。这个命令会直接托管public
文件夹作为静态内容,并同时启动functions
里的 API。在浏览器中访问http://localhost:8788
即可测试。
部署到 Cloudflare Pages:
- 将您的整个项目推送到一个 GitHub 仓库。
- 在 Cloudflare 仪表盘中,新建一个 Pages 项目,连接到您的 GitHub 仓库。
- 在“构建设置”中,选择框架预设为
Hugo
。Cloudflare 会自动填好构建命令 (hugo
) 和输出目录 (public
)。 - 关键一步:部署完成后,进入项目的 设置 -> 函数 -> D1 数据库绑定,添加一个绑定:变量名为
DB
,值为您创建的 D1 数据库。 - 最后一步:对您的数据库运行一次远程迁移,在线上创建数据表:
wrangler d1 migrations apply <你的数据库名> --remote
。
至此,您的云端书签网站就完全上线了!
第二部分:开发 Chrome 扩展实现自动同步
为了让书签管理无缝融入日常浏览,我们将创建一个 Chrome 扩展,实现“随手收藏,自动同步”。
第一步:扩展的工作原理
扩展的核心是一个在后台运行的 Service Worker (background.js
)。它会使用 Chrome 提供的 chrome.bookmarks.onCreated
API 来监听书签创建事件。一旦有新书签被创建,它就会获取书签的标题和 URL,然后通过 fetch
API 将这些信息发送到我们网站的 /api/bookmarks
端点。
第二步:创建扩展文件 (manifest.json
)
这是扩展的配置文件,声明了它的名称权限和后台脚本。
{
"manifest_version": 3
"name": "我的书签自动同步"
"version": "1.0"
"permissions": [ "bookmarks" ]
"host_permissions": [ "https://你的域名.pages.dev/" ]
"background": { "service_worker": "background.js" }
}
"permissions": ["bookmarks"]
: 请求访问书签的权限。"host_permissions"
: 请求向你的网站发送网络请求的权限。
第三步:编写后台脚本 (background.js
)
这个脚本是扩展的全部逻辑所在。
const API_ENDPOINT = 'https://你的域名.pages.dev/api/bookmarks'
// 监听书签创建事件
chrome.bookmarks.onCreated.addListener((id bookmark) => {
if (!bookmark.url) return // 忽略文件夹
const data = {
name: bookmark.title || '无标题'
url: bookmark.url
category: '来自浏览器'
tags: 'auto-sync'
}
// 发送数据到 API
fetch(API_ENDPOINT {
method: 'POST'
headers: { 'Content-Type': 'application/json' }
body: JSON.stringify(data)
})
.then(response => console.log('书签同步成功:' response.status))
.catch(error => console.error('书签同步失败:' error))
})
- 注意:
API_ENDPOINT
必须是您自己的正确的线上域名。
第四步:加载与测试扩展
- 在 Chrome 地址栏输入
chrome://extensions
。 - 打开右上角的“开发者模式”。
- 点击“加载已解压的扩展程序”,选择包含
manifest.json
和background.js
的文件夹。 - 加载成功后,随便收藏一个网页,然后回到您的书签网站刷新查看,新书签应该已经同步过来了!
好的,完全没问题!您提供的这个场景——只保护 /logs
路径,而让网站主体 (/
) 保持公开——是一个非常常见且实用的需求。
我将为您撰写一篇极其详细的从零开始的严格按照最新 Cloudflare 界面和您的精确需求的终极指南。这篇文章将是您未来随时可以参考的绝对正确的操作手册。
使用 Cloudflare Access 为你的网站特定页面添加安全登录
第一步:注册并进入 Cloudflare Zero Trust
这是我们所有安全配置的起点。
- 访问 Zero Trust 仪表盘:
- 在浏览器中打开
https://one.dash.cloudflare.com
。
- 在浏览器中打开
- 首次登录/注册:
- 如果您已经登录了主 Cloudflare 账户,它可能会自动带您进入。
- 如果是第一次,它会引导您完成一个简单的注册流程。您需要输入您的邮箱,然后去邮箱里点击验证链接。
- 设置团队名称 (Set up your team):
- 首次进入时,Cloudflare 会要求您创建一个“团队名称”。这只是一个内部标识,您可以输入任何您喜欢的独一无二的名字(比如
yyszone-team
),然后点击 “Next”。 - 在接下来的计划选择页面,选择 Free plan (免费计划),它包含了我们所需的所有功能。
- 首次进入时,Cloudflare 会要求您创建一个“团队名称”。这只是一个内部标识,您可以输入任何您喜欢的独一无二的名字(比如
现在,您已经成功进入了 Zero Trust 的主控制台。
第二步:创建服务令牌 (获取您的专属“账号密码”)
服务令牌是专门为程序化访问设计的“固定账号密码”,它由一个 Client ID (用户名) 和一个 Client Secret (密码) 组成。
-
导航到服务认证:
- 在 Zero Trust 仪表盘的左侧菜单中,找到 Access,然后点击它的子菜单 服务认证 (Service Auth)。
- URL:
https://one.dash.cloudflare.com/<你的账户ID>/access/service-tokens
-
创建服务令牌:
- 点击蓝色的 创建服务令牌 (Create Service Token) 按钮。
- 令牌名称 (Token Name): 输入一个有意义的名字,比如
Logs-Admin-Token
。 - 服务令牌持续时间 (Service Token Duration): 选择
无期限 (No Expiration)
或您希望的时长。 - 点击 生成令牌 (Generate Token)。
-
立即复制并安全保存!
- 一个弹窗会出现,显示您的 客户端 ID (Client ID) 和 客户端密钥 (Client Secret)。
- 警告:客户端密钥 (Client Secret) 只会在这里显示一次! 请务必立即将它复制到一个安全的地方(比如您的密码管理器)。一旦关闭这个窗口,您将永远无法再次查看它。
第三步:创建 Access 应用程序 (定义保护目标)
现在,我们要告诉 Cloudflare,我们具体要保护哪个网站的哪个页面。
-
进入应用程序列表:
- 在左侧菜单中,点击 Access -> 应用程序 (Applications)。
-
添加应用程序:
- 点击蓝色的 添加应用程序 (Add an application) 按钮。
- 选择第一个选项,自托管 (Self-hosted)。
-
配置应用程序 (这是最关键的一步):
- 应用程序名称 (Application name):
书签管理器 - 日志页面
- 会话时长 (Session Duration): 选择
24 hours
或更长。 - 公共主机名 (Public Hostname):
- 子域 (Subdomain):
bm
- 域 (Domain):
yysresume.work
- 路径 (Path):
/logs
- 重要:在这里,我们精确地指定了只保护
/logs
这个路径。这意味着,当用户访问https://bm.yysresume.work/
(首页) 时,不会触发登录只有当他们访问https://bm.yysresume.work/logs
时,门卫才会出来检查。
- 重要:在这里,我们精确地指定了只保护
- 子域 (Subdomain):
- 跳过高级设置:下方的所有其他设置都保持默认。
- 点击页面最下方的 下一步 (Next) 按钮。
- 应用程序名称 (Application name):
第四步:创建唯一的 Allow
策略
这是我们将“门规”和“钥匙”关联起来的地方。
-
基本信息:
- 策略名称 (Policy name):
仅限管理员密码访问
- 操作 (Action):
Allow
- 策略名称 (Policy name):
-
配置唯一的规则:
- 在 "包括 (Include)" 部分,创建一条规则:
- 选择器 (Selector): 选择 服务令牌 (Service Token)。
- 值 (Value): 从下拉菜单中,选择我们刚刚创建的
Logs-Admin-Token
。
- 确保这是唯一的
Allow
规则! 不要添加任何其他基于邮箱或IP的规则。
- 在 "包括 (Include)" 部分,创建一条规则:
-
保存策略:
- 滚动到页面底部,点击蓝色的 添加策略 (Add policy) 按钮。
- 在接下来的 "Setup" 页面,保持默认设置,点击 添加应用程序 (Add application)。
第五步:最终测试
现在,您的安全配置已经全部完成。
-
测试公开页面:
- 打开一个新的无痕浏览器窗口。
- 访问您的网站首页:
https://bm.yysresume.work
- 结果:您应该能直接看到您的书签管理器,无需任何登录。
-
测试受保护页面:
- 在同一个无痕窗口中,现在访问您的日志页面:
https://bm.yysresume.work/logs
- 结果:这一次,您会被 Cloudflare Access 拦截,并看到一个专门用于输入服务令牌的登录页面。
- 截图描述:页面标题为 "Access to bm.yysresume.work",下面有两个输入框:"CF-Access-Client-Id" 和 "CF-Access-Client-Secret"。
- 在同一个无痕窗口中,现在访问您的日志页面:
-
使用您的“账号密码”登录(好像没用):
- 在登录页面中,输入您在第二步保存的 Client ID 和 Client Secret。
- 点击 Sign in。
- 成功! 您现在应该能看到您的日志页面了。
- 登录方法:你的应用->登录方法->管理登录方法->登录方式(新增)
- 可以加入github登录,去策略添加->(选择器Login Methods, 值 github(登录方式要打勾才行))
- 登录界面
结语
通过这个项目,不仅亲手打造了一个完全属于自己的功能强大的云端书签管理器,还掌握了从前端构建后端 API 开发数据库设计到浏览器扩展集成的全栈技能。
这段旅程充满了挑战,但每一次调试每一次修复,都让我们对技术的理解更深一层。现在,享受你的成果吧!这个项目将成为你数字世界里一个得心应手的强大工具。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=451
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)