本頁目的
在限時分享連結中,若想直接使用核發時決定的條件,除了驗證 URL 簽章之外,還需要統一從哪裡取得值。 本頁以一個範例說明:在 URL 中包含報表類型與輸出格式,並回傳預覽用的 JSON。 本頁適用於 Laravel 13。URL 產生的整體說明請參閱 URL 生成,取得輸入的基礎請參閱 HTTP Request。簽章保護的範圍
input() 不僅處理 query string,也會處理 body。Laravel 在合併這些輸入時,body 的值優先於 query string 的值。
相對地,query() 只會取得 query string 的值。
簽章驗證成功,與之後讀取的值是否已簽章,是兩件需要分別確認的事。
實作限時預覽連結
1. 定義進行驗證的路由
在routes/web.php 中定義必須帶有簽章的具名路由。
這裡不操作資料庫或檔案,只回傳收到的條件。
signedmiddleware 會在 closure 執行前驗證簽章與有效期限。若無效則回傳403。- 使用
query()明確地從 query string 取得處理所需的值。 - 驗證是針對取得的陣列進行。簽章驗證並不保證值的型別或業務上允許的範圍。
本範例傳給
Validator::make() 的只有以 query() 取出的值。
若在用來驗證已簽章 query 值的地方改用 $request->all(),就會處理到包含 body 在內的輸入。2. 在可信任的核發流程中產生 URL
註冊具名路由後,在核發連結的處理中使用以下程式碼。report 與 format 不是路徑的佔位符,因此會被加入 query string。
expires 與 signature。
expires 與 signature 是 Laravel 使用的保留參數,請勿將其作為業務用的參數名稱。
在實際應用程式中公開核發流程時,請勿讓任何人都能以任意條件核發連結,並進行必要的認證與授權。
3. 確認正常使用
在有效期限內直接開啟核發的 URL,會回傳以下 JSON。signed middleware 會回傳 403。
簽章 URL 並非一次性 token。在本範例中,有效期限內可重複使用同一個 URL。
若只允許使用一次,需要在簽章之外另行管理已使用狀態。
區分排除於驗證之外的值
若想允許前端加上的頁碼等參數,可以透過hasValidSignatureWhileIgnoring(['page']) 將其排除於簽章驗證之外。
不過,被排除的值任何人都能修改,因此請勿將其視為已簽章的條件。
例如,顯示用的 page 與核發時固定的 report、format 作用不同。
請勿僅為了方便,就排除用來判斷目標資料、收件者、費用等的值。
使用相對簽章時
在簽章中不包含網域的設計下,需搭配產生時的absolute: false 與驗證時的 signed:relative。
middleware('signed') 改為 middleware('signed:relative')。
即使使用相對簽章,body 也不會被簽章,因此以 query() 取得值的原則不變。
實作檢查清單
- 接收路由強制要求簽章驗證。
- 以
query()取得已簽章的 query 值。 - 另外驗證值的格式與允許範圍。
- 未將排除於簽章驗證之外的值當作核發時固定的條件使用。
- 產生端與驗證端的絕對簽章、相對簽章設定一致。
- 未將知道 URL 視同已登入使用者的權限。
相關頁面與一手資料
- URL 生成:簽章 URL 的 API 與對無效簽章的回應
- HTTP Request:取得輸入值與 query string
- 驗證:驗證輸入格式與允許的值
- Laravel 官方文件:Signed URLs
- Laravel 官方文件:Retrieving input from the query string
- Laravel Framework:UrlGenerator
- Laravel Framework:ValidateSignature