必须用签名随机短码替代可预测ID,服务端校验时效性、访问次数及权限,重定向前严格鉴权并防止信息泄露。
token 或 id
直接暴露原始 URL 的 ID(如数据库自增主键)或未签名的 token,会让攻击者通过递增、爆破等方式批量还原敏感链接。必须切断「短码 → 原始 URL」的可预测映射关系。
123、124)作为短码;改用随机字符串(如 aB3xK9),长度 ≥ 6,字符集排除易混淆字符(0/O/l/I)short_code 是否在有效期内、是否已被禁用、是否超出访问次数限制(存于 Redis 中,用 INCR + EXPIRE 实现)user_id=、file_id= 等)hash_hmac() 签名短码防止篡改单纯随机短码仍可能被伪造或重放。需绑定业务上下文并签名,确保短码不可逆、不可伪造。
function generateShortCode($originalUrl, $secretKey) { $timestamp = time(); $payload = $originalUrl . '|' . $timestamp; $hmac = hash_hmac('sha256', $payload, $secretKey); $code = substr(base64_encode($hmac), 0, 6); // 截取生成短码 return str_replace(['+', '/', '='], ['a', 'b', 'c'], $code); } function verifyShortCode($code, $originalUrl, $timestamp, $secretKey) { $payload = $originalUrl . '|' . $timestamp; $expected = hash_hmac('sha256', $payload, $secretKey); $expectedCode = substr(base64_encode($expected), 0, 6); $expectedCode = str_replace(['+', '/', '='], ['a', 'b', 'c'], $expectedCode); return hash_equals($expectedCode, $code); // 防时序攻击 }
关键点:hash_equals() 防止时序攻击;$timestamp 参与签名,后续可校验是否超时(如 24 小时);$secretKey 必须是强随机、独立存储的密钥(不硬编码在代码里)。
还原不是终点,而是访问控制的起点。不能只查出原始 URL 就 302 跳转,必须确认当前请求具备访问该资源的权限。
立即学习“PHP免费学习笔记(深入)”;
/download?file_id=789),需从 session 或 JWT 中提取当前 user_id,再查数据库确认该用户是否拥有该 file_id 的读权限UPDATE ... WHERE used = 0 + affected_rows === 1 保证原子性)常见疏漏是开发环境残留调试逻辑,或错误使用 header() 导致跳转信息被中间件/CDN 缓存或透出。
expose_php = On(php.ini),防止响应头泄露 PHP 版本exit; 或 die();,否则后续代码仍会执行(尤其在未严格控制流程时)echo ''),否则触发 headers already sent 错误,可能暴露路径或堆栈
add_header X-Redirect-URL 类似规则,把原始 URL 写进响应头
# php
# redis
# nginx
# 编码
# session
# mac
# 栈
# cdn
# 开发环境
# 密码重置
# red
# 中间件
# echo
# timestamp
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win11怎么关闭开机声音_Win11系统启动提示音静音【教程】
如何使用Golang反射将map转换为struct_Golang reflect类型映射技巧
如何在 Go 中高效缓存与分发网络视频流
Laravel 查询 JSON 列:高效筛选包含数组中任意值的记录
Win10怎么更改用户名 Win10修改账户名称操作教程
c++如何获取map中所有的键_C++遍历键值对提取所有key的方法
Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
PHP怎么接收前端传的时间戳_处理时间戳参数转换技巧汇总【指南】
php串口通信波特率怎么选_根据硬件手册设置正确波特率【方法】
Win11怎么激活Windows10_Win11激活Win10系统方法【步骤】
Win11怎么关闭应用权限_Windows11相机麦克风隐私管理
windows 10应用商店区域怎么改_windows 10微软商店切换地区方法
Python文件管理规范_工程实践说明【指导】
Windows服务持续崩溃怎样修复_系统服务保护机制解析
c++怎么使用std::filesystem遍历文件夹_c++ 递归查找文件与权限修改【技巧】
Win11怎么把图标拖到任务栏_Win11固定应用快捷方式指南【方法】
php怎么下载安装后无法解析php文件_服务器配置检查【解答】
c++如何判断文件是否存在_c++ filesystem库用法
Win11怎么设置鼠标宏_Win11鼠标按键自定义编程教程【详解】
MySQL 中使用 IF 和 CASE 实现查询字段的条件映射
Python对象比较与排序_集合使用说明【指导】
php条件判断怎么写_ifelse和switchcase的使用区别【对比】
Windows10电脑怎么设置文件权限_Win10安全选项卡所有者修改
如何使用Golang实现文件追加操作_向已有文件追加数据
Win11怎么开启移动热点_Windows11共享网络给手机设置教程
Win11怎么设置ip地址_Windows 11手动配置网络IP教程【详解】
MySQL 中使用 IF 和 CASE 实现查询字段条件化显示
如何在 Go 结构体中正确初始化 map 字段
如何在 Go 同包不同文件中正确引用结构体
Win11怎么清理C盘系统错误报告_Win11清理系统错误报告技巧【教程】
Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】
Win10怎样安装Excel数据分析工具_Win10安装分析工具包步骤【教程】
Mac怎么给文件夹加密_Mac创建加密磁盘映像教程【安全】
Windows怎样关闭开始菜单推荐广告_Windows关闭开始菜单推荐设置【步骤】
Windows10如何查看保存的WiFi密码_Win10命令行netsh wlan查询
Golang如何遍历目录文件_Golang filepath.Walk目录遍历操作方法
Windows7怎么找回经典开始菜单_Windows7经典菜单找回步骤【方法】
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
Win11怎么恢复旧版开始菜单_通过软件还原Win10风格菜单【详解】
Win11如何隐藏桌面图标 Win11一键隐藏/显示桌面图标【指南】
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
c# 在高并发下使用反射发射(Reflection.Emit)的性能
Mac的访达(Finder)怎么用_Mac文件管理入门教程【详解】
php查询数据怎么分组_groupby分组查询配合聚合函数【技巧】
c++ std::atomic如何保证原子性 c++ CAS操作原理【底层】
Go 中 defer 语句在 goroutine 内部不返回时不会执行
php修改数据怎么批量改状态_批量更新status字段值技巧【操作】
用lighttpd能运行php吗_lighttpd配置php步骤【教程】
php内存溢出怎么排查_php内存限制调试与优化方法【说明】
MAC怎么截图并快速编辑_MAC自带截图快捷键与标注工具使用【方法】
2026-01-04
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。