生成的下载链接刚过六十分钟就返回 403,链接里 exp 参数看着还没到,服务器时间和本地时间差八小时,改系统时区后又变成提前失效。日志里能对上时间点,这种反而好排。

生成签名时用 date() 取本地时间,校验时用 time() 取 UTC 时间戳,两边基准不同。签名串里还把时区偏移拼了进去。这一点先确认清楚,后面就不用反复试。

$exp = time() + 3600;
$sig = hash_hmac( 'sha256', $file . '|' . $exp, SECRET );
// 校验: hash_equals( $sig, $_GET['sig'] ) && time() < $exp

「签名链接过期」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

报错里带路径的,先去看那个路径在不在、权限对不对。同一份配置存在多处的,先确认改的是被加载的那一份。

处理上按这个顺序:生成和校验统一用 time() 取 UTC 秒数,别混用 date();签名里只放 exp 绝对时间戳,不放格式化字符串;生成链接后等六十一分钟再请求,确认返回 403 且提示过期。

结果对不对很好判断,链接在有效期内可下载,超过一小时后返回 403 并提示已过期。

作者 9823189