首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >短链接服务全栈开发实战:从零构建支持OAuth双平台登录、密码保护与审计日志的企业级短链系统

短链接服务全栈开发实战:从零构建支持OAuth双平台登录、密码保护与审计日志的企业级短链系统

作者头像
佛系豪豪吖
发布2026-06-22 21:01:40
发布2026-06-22 21:01:40
1000
举报

项目背景

在日常开发与运营中,长链接分享既不美观也不便于追踪。于是我在 s.rmzdb.cloud 域名下从零搭建了一套短链接服务,支持用户注册登录、短链生成管理、VIP 会员、二维码生成等功能。并在近期完成了三项重磅扩展 + 双平台 OAuth 接入。

项目地址https://s.rmzdb.cloud/


一、GitCode OAuth 第三方登录

接入 GitCode(CSDN 旗下代码托管平台)OAuth 2.0 授权登录,实现管理员和普通用户双重场景。

遇到的坑

  1. HTTPS 模块引用问题https.request() 必须从顶层 const https = require('https') 引用,闭包内动态引用会导致 TLS 握手失败
  2. State 持久化:OAuth state 参数不能存在内存中(Node 重启即丢失),必须存入 SQLite oauth_states 持久化
  3. Token 端点格式:GitCode 的 /oauth/token 要求 Content-Type: application/x-www-form-urlencoded,而非 JSON
  4. Nginx 旧域名污染:旧配置文件里 s.rmzdb.site 的通配代理将前端请求发到后端 API,返回空 [] JSON,修复后恢复正常

统一回调端点

代码语言:javascript
复制
// 通过 oauth_states 表的 target_type 自动路由 admin/user
app.get('/api/gitcode/callback', (req, res) => {
    const { code, state } = req.query;
    db.get('SELECT * FROM oauth_states WHERE state=?', [state], (err, row) => {
        const isUser = row.target_type === 'user';
        // token 交换 → 用户信息 → 创建/绑定账号 → 生成 session
    });
});

二、Gitee OAuth 第三方登录

在同一天接入 Gitee(码云)OAuth,与 GitCode 并列共存,用户登录弹窗底部同时展示两个平台按钮。

双平台对比

平台

回调地址

Token 格式

用户信息端点

GitCode

/api/gitcode/callback

form-urlencoded

api.gitcode.com/api/v5/user

Gitee

/api/gitee/callback

JSON

gitee.com/api/v5/user

Gitee 特有处理

  • 回调地址不一致:Gitee 填的是 s.rmzdb.cloud/api/gitee/callback
  • postMessage 跨窗口:授权弹窗关闭后通过 window.opener.postMessage({type:'gitee_login',...}) 向父窗口传递 session
  • provider 字段oauth_states 表新增 provider 列区分 gitcode / gitee

三、访问密码保护

敏感链接需要加锁,访问时输入密码才能跳转。

实现流程

  • 用户访问 s.rmzdb.cloud/A1b2C3
  • 检测到 password 字段 → 302 跳转到 /p/A1b2C3(自包含 HTML 密码中间页)
  • 用户输入密码 → POST /api/verify-password
  • SHA-256 比对 →

返回目标 URL 前端跳转 /

提示"密码错误"

安全措施

  • 密码使用 crypto.createHash('sha256') 存储,不存明文
  • 密码中间页是自包含 HTML 页面,不依赖外部 CDN
  • 错误密码不返回任何 URL 信息

四、操作审计日志

所有关键操作记录到 audit_logs 表,管理员可在后台实时查看。

覆盖范围

操作

记录内容

创建/编辑/删除链接

操作人、短码、目标 URL、IP

VIP 订单审核

操作人、订单 ID、套餐、操作结果

删除用户/链接(管理员)

操作人、目标、IP

自定义域名设置

操作人、域名、IP

管理后台新增「审计日志」面板,按时间倒序展示,动作标签自动着色:删除=红、驳回=黄、通过=绿。


五、UI 全面去 Emoji

全部 46 个 emoji 图标替换为 Lucide 风格 inline SVG,零外部依赖。

代码语言:javascript
复制
<!-- Before: emoji -->
<span> 短链接</span>

<!-- After: inline SVG -->
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" 
     stroke="currentColor" stroke-width="2">
  <path d="M10 13a5 5 0 0 0 7.54.54l3-3..."/>
</svg>
短链接

优势:像素级可控、任何设备渲染一致、不依赖系统 emoji 字体。


六、踩坑总结

问题

根因

解决

GitCode grant_type 为空

闭包内 https 引用丢失

提升到顶层 require

State 重启丢失

存 JavaScript 对象内存中

改存 SQLite 表

Gitee 回调 404

回调地址写错路径

改为 /api/gitee/callback

Nginx 502

PHP 8.3 FPM 不存在

改为 php8.4-fpm.sock

REST API 被拦截

EdgeOne Bot 防护

--resolve 直连源站

postMessage 未触发

只监听了 gitcode_login

新增 gitee_login 事件


技术栈一览

  • 后端:Node.js + Express + SQLite3
  • 前端:Vue 2 + Element UI(CDN,零构建)
  • OAuth:GitCode OAuth 2.0 + Gitee OAuth 2.0
  • 部署:Nginx 反向代理 + SSL(Let's Encrypt 通配符证书)
  • 安全:SHA-256 密码哈希 + 审计日志 + Token 认证 + 输入过滤

成果展示

访问 https://s.rmzdb.cloud/ 体验完整功能:

  • 注册/登录(密码 + GitCode + Gitee 三选一)
  • 生成短链接(可选密码保护 + 备注)
  • 个人中心管理历史链接(编辑、删除、二维码)
  • VIP 会员升级
  • 自定义域名(CNAME 解析)
  • 管理员后台:仪表盘、会员审核、用户管理、审计日志

这篇分享记录了从零到一的完整开发过程,希望能给同样在做短链接服务或 OAuth 集成的朋友一些参考。

本文为作者原创,未经授权禁止转载、洗稿、搬运。如需引用请保留原文链接。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目背景
  • 一、GitCode OAuth 第三方登录
    • 遇到的坑
    • 统一回调端点
  • 二、Gitee OAuth 第三方登录
    • 双平台对比
    • Gitee 特有处理
  • 三、访问密码保护
    • 实现流程
    • 安全措施
  • 四、操作审计日志
    • 覆盖范围
  • 五、UI 全面去 Emoji
  • 六、踩坑总结
  • 技术栈一览
  • 成果展示
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档