このページの目的
期限付きの共有リンクで、発行時に決めた条件をそのまま使いたい場合は、URLの署名検証に加えて値をどこから取得するかを揃えます。 このページでは、レポートの種類と出力形式をURLに含め、プレビュー用のJSONを返す例で説明します。 対象はLaravel 13です。URL生成全般はURL生成、入力取得の基本はHTTPリクエストを参照してください。署名で保護される範囲
input() はクエリ文字列だけでなく本文も扱うAPIです。Laravelはこれらの入力を統合する際、本文の値をクエリ文字列より優先します。
一方、query() はクエリ文字列だけを取得します。
署名検証が成功したことと、その後に読み取った値が署名済みであることは別の確認事項です。
期限付きプレビューリンクを実装する
1. 検証するルートを定義する
routes/web.php に、署名を必須とする名前付きルートを定義します。
ここではDBやファイルを操作せず、受け取った条件だけを返します。
signedミドルウェアが、クロージャの実行前に署名と有効期限を検証します。無効なら403を返します。query()で、処理に使う値をクエリ文字列から明示的に取得します。- バリデーションは取得した配列に対して行います。署名検証は値の型や業務上の許可範囲を保証するものではありません。
この例で
Validator::make() に渡しているのは、query() で取り出した値だけです。
署名済みクエリの検証を目的とする箇所で $request->all() に置き換えると、本文を含む入力を扱うことになります。2. 信頼できる発行処理でURLを生成する
名前付きルートの登録後、リンクを発行する処理で次のコードを使います。report と format はパスのプレースホルダーではないため、クエリ文字列に追加されます。
expires と signature が含まれます。
expires と signature はLaravelが使用する予約済みパラメータなので、業務用のパラメータ名として渡さないでください。
実際のアプリケーションで発行処理を公開する場合は、任意の条件で誰でもリンクを発行できる状態にせず、必要な認証や認可を行ってください。
3. 通常の利用を確認する
発行したURLをそのまま開くと、有効期限内であれば次のJSONが返ります。signed ミドルウェアが 403 を返します。
署名付きURLは使い捨てトークンではありません。この例では、期限内の同じURLを再利用できます。
一度だけ利用させたい場合は、署名とは別に使用済み状態を管理する必要があります。
検証から除外する値を分ける
フロントエンドが追加するページ番号などを許可したい場合、hasValidSignatureWhileIgnoring(['page']) で署名検証から除外できます。
ただし、除外した値は誰でも変更できるため、署名済み条件として扱わないでください。
たとえば、表示用の page と、発行時に固定する report、format は役割が異なります。
対象データ、受信者、料金などの判断に使う値を、利便性だけを理由に除外しないようにします。
相対署名を使う場合
ドメインを署名に含めない設計では、生成時のabsolute: false と検証時の signed:relative を組み合わせます。
middleware('signed') を middleware('signed:relative') に変更します。
相対署名でも本文は署名されないので、query() で取得する方針は変わりません。
実装時のチェックリスト
- 受信ルートで署名検証を必須にしている。
- 署名済みクエリ値を
query()から取得している。 - 値の形式や許可範囲を別途検証している。
- 署名検証から除外した値を、発行時に固定された条件として使っていない。
- 絶対署名・相対署名の設定を生成側と検証側で揃えている。
- URLを知っていることと、ログインユーザーの権限を同一視していない。
関連ページと一次情報
- URL生成:署名付きURLのAPIと無効な署名へのレスポンス
- HTTPリクエスト:入力値とクエリ文字列の取得
- バリデーション:入力形式と許可する値の検証
- Laravel公式ドキュメント:Signed URLs
- Laravel公式ドキュメント:Retrieving input from the query string
- Laravel Framework:UrlGenerator
- Laravel Framework:ValidateSignature