一句話:query string 是網址「?」後面那串、是網址的一部分(複製網址就帶走);request header 是塞在 HTTP 請求暗處的標頭(複製網址不會帶走)。pre-signed URL 的整個巧思,就是把認證資訊全放進 query string。
一個 HTTP 請求能從兩個地方夾帶資訊,差別在於「這資訊在不在網址裡」。
網址裡問號 ? 之後那一串,用 key=value 表示、& 串接:
https://x.com/search?q=cat&page=2
└────┬────┘
query string:q=cat、page=2
它是網址的一部分——複製整條網址,這些資訊就跟著走,貼到瀏覽器、丟進 curl 都在。
夾在 HTTP 請求暗處的一組 名稱: 值,網址裡看不到:
GET /search?q=cat HTTP/1.1
Host: x.com
Content-Type: application/json
Authorization: Bearer abc123
它不在網址裡——複製網址不會帶走 header,得靠發請求的程式另外附上。
比喻:query string=寫在信封正面的字(誰都看得到、影印信封就複製走);header=塞進信封的附箋(要拆信才看得到、影印信封帶不到)。
一般 API 認證把「我是誰、有沒有權限」放在 Authorization header。但這樣就沒辦法「只給一條網址」——header 塞不進網址,複製網址就掉了。
pre-signed URL 反其道而行:把認證資訊(誰、期限、簽章)全部改放進 query string(就是那串 X-Amz-* 參數)。於是整個授權「凝結」進一條網址,複製即用。代價是——這些認證資訊都攤在網址上,所以它不能無限期有效、也會被記進各種 log(這是 Level 5 的安全題)。