temporaryUrl() 生成带签名的临时 URL,需配置支持签名的磁盘(如 s3 或启用 temporary_url 的 local),但其签名不被 signed 中间件自动校验,须配合 signed 路由和控制器收口访问。
用
生成带签名的临时 URL
在 Laravel 中,
是最直接的方式,适用于
或本地磁盘(需启用
驱动并配置
支持)。它会自动添加
、
和可选的
参数,验证逻辑由 Laravel 内置中间件
处理。
注意:该方法仅对使用
或
生成的 URL 生效,普通
不参与签名验证。
必须使用支持签名的磁盘(如
、
配合
驱动 +
配置)
本地磁盘默认不支持
,需在
中为该磁盘显式设置
生成的 URL 有效期从服务器当前时间起算,不依赖客户端时钟
签名 URL 必须通过
中间件校验
所有签名 URL 的请求都会被 Laravel 自动拦截并校验签名与过期时间,前提是
路由
已绑定
中间件。Laravel 不会自动为
生成的链接强制走该流程——它只对通过
生成的路由生效。所以,如果你用
生成的是文件直链(如 S3),你得自己在对应控制器里手动校验。
正确做法是:把文件访问收口到一个带签名路由的控制器方法中,例如:
然后在控制器中用
或直接返回
,而不是暴露原始
给
前端
。
中间件只检查
和
查询参数,不校验路径或文件名
若绕过路由直接访问
返回的 S3 链接,签名机制完全失效——S3 不认识 Laravel 的签名规则
自定义校验逻辑可用
手动触发
更适合控制访问入口
当你要保护的是「某个操作行为」(如下载、预览、重置),而不是单纯一个文件路径,优先用
。它把签名逻辑和路由绑定在一起,天然适配
中间件,且不依赖存储驱动能力。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
示例:生成一个 30 分钟有效的下载链接
此时
类似
,访问时会经由
中间件自动校验。
路由名必须已在
中定义,并显式绑定
中间件
签名基于当前
和完整查询字符串生成,篡改任意参数(包括
)都会导致验证失败
不能用于大文件流式响应场景(如视频播放),因为每次请求都走 PHP 控制器,有内存和超时风险
签名失效的常见原因和调试建议
签名 URL 访问返回 403 最常见的不是代码写错,而是环境或配置偏差。
服务器时间与 NTP 不同步:Laravel 校验
基于服务端
,误差超过 15 秒即拒绝(默认容差);用
命令确认系统时间
在多台服务器上不一致:负载均衡下必须共用同一
,否则签名无法互相验证
URL 被代理或 CDN 重写:某些 CDN 会 strip 掉
或
参数,或强制跳转导致 query string 丢失
使用了
(无
)但没设过期时间:它生成的是永久签名,不推荐用于防未授权访问
调试时可在中间件中加日志,或临时在控制器里 dump
和
的返回值,确认是签名错还是时间错。
temporaryUrl()temporaryUrl()Storage::disk('s3')urltemporary_urlsignatureexpiresrelativeIlluminate\Http\Middleware\ValidateSignatureURL::temporarySignedRoute()Storage::temporaryUrl()url()s3localurltemporary_urltemporaryUrl()config/filesystems.php'url' => env('APP_URL'), 'temporary_url' => truesignedsignedStorage::temporaryUrl()URL::temporarySignedRoute()temporaryUrl()Route::get('/download/{filename}', [DownloadController::class, 'show'])
->name('download.show')
->middleware('signed');Storage::url()response()->file()temporaryUrl()signedsignatureexpirestemporaryUrl()URL::hasValidSignature($request)URL::temporarySignedRoute()URL::temporarySignedRoute()signeduse Illuminate\Support\Facades\URL;
$url = URL::temporarySignedRoute(
'download.show',
now()->addMinutes(30),
['filename' => 'report.pdf']
);$url/download/report.pdf?expires=1717023600&signature=abc123...signedroutes/web.phpsignedAPP_KEYfilenameexpiresnow()dateAPP_KEYAPP_KEYsignatureexpiresURL::signedRoute()temporary$request->fullUrl()URL::hasValidSignature($request, 300)