En presignerad URL i S3 är en tillfällig länk till ett objekt i en privat bucket. Den bär en signatur i sin frågesträng, så den som har den kan ladda ner (eller ladda upp) objektet utan AWS-uppgifter tills länken går ut, och bucketen blir aldrig publik. Du skapar den med dina egna nycklar, i din kod eller från AWS CLI, och den kan gälla från 1 sekund upp till 7 dagar. Den här guiden går igenom hur det fungerar, vad varje X-Amz-*-parameter betyder, hur länge den kan gälla, kod för nedladdningar och uppladdningar och de fel du mest sannolikt stöter på. Gränserna är hämtade från dokumentationen för AWS och Cloudflare i oktober 2026.
Presignerade URL:er i S3 i korthet
| Fråga | Svar |
|---|---|
| Vad ger den tillgång till? | En operation (GET, PUT, HEAD, DELETE…) på ett objekt |
| Längsta giltighet | 7 dagar (604 800 sekunder) med SigV4 och nycklar för en IAM-användare |
| Giltighet med tillfälliga nycklar | Upphör när rollsessionen eller STS-uppgifterna upphör, det som inträffar först |
| Intervall i S3-konsolen | 1 minut till 12 timmar |
| Standardgiltighet | 3 600 s i AWS CLI och boto3, 900 s i presignern för JavaScript v3 |
| Kan den användas flera gånger? | Ja, så ofta som någon vill tills den går ut |
| Kan en enskild URL återkallas? | Nej, bara genom att återkalla de signerande uppgifterna eller neka i en policy |
| Anropar S3 när man skapar en? | Nej, signaturen beräknas lokalt |
Så fungerar en presignerad URL
- Din kod (eller CLI:t) tar bucketen, objektnyckeln, HTTP-metoden och en giltighetstid.
- SDK:n signerar de värdena med din hemliga åtkomstnyckel med AWS Signature Version 4. Inget skickas till S3 i det här steget.
- Du ger den resulterande URL:en till någon: en webbläsare, en kollega, en mobilapp.
- När de använder den beräknar S3 om signaturen med den hemlighet som hör till åtkomstnyckeln i URL:en. Om den stämmer, URL:en inte har gått ut och signeraren har behörighet att utföra operationen, går förfrågan igenom.
URL:en bär behörigheterna hos den som signerade den. AWS är tydliga med detta: om IAM-användaren eller rollen som skapade URL:en inte kan läsa objektet returnerar URL:en 403, hur giltig signaturen än är.
Vad X-Amz-parametrarna betyder
En presignerad URL med SigV4 ser ut så här (radbrytningar tillagda):
https://my-bucket.s3.eu-west-1.amazonaws.com/reports/q3.pdf
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20261017%2Feu-west-1%2Fs3%2Faws4_request
&X-Amz-Date=20261017T093000Z
&X-Amz-Expires=3600
&X-Amz-SignedHeaders=host
&X-Amz-Signature=5f2c...e91a
| Parameter | Betydelse |
|---|---|
X-Amz-Algorithm | Signeringsalgoritmen: AWS4-HMAC-SHA256 för SigV4 |
X-Amz-Credential | Åtkomstnyckel-ID plus omfång: <key-id>/<YYYYMMDD>/<region>/s3/aws4_request |
X-Amz-Date | När URL:en signerades, i UTC, yyyyMMddTHHmmssZ |
X-Amz-Expires | Hur många sekunder URL:en gäller efter X-Amz-Date, från 1 till 604800 |
X-Amz-SignedHeaders | Headers som omfattas av signaturen, alltid minst host |
X-Amz-Signature | Signaturen, 64 hexadecimala tecken |
X-Amz-Security-Token | Finns bara när URL:en signerades med tillfälliga uppgifter (STS, roller, EC2, ECS, SSO) |
Ändra någon signerad del (nyckeln, metoden, giltigheten eller en signerad header) så stämmer signaturen inte längre. Notera också vad URL:en avslöjar i klartext: bucketens namn, hela objektnyckeln och ditt åtkomstnyckel-ID. Den hemliga nyckeln finns aldrig i URL:en.
Hur länge en presignerad URL gäller
Gränsen beror på uppgifterna som signerar den:
| Signerad med | Längsta giltighet |
|---|---|
| Åtkomstnycklar för IAM-användare (SigV4) | 7 dagar, eftersom själva signeringsnyckeln i SigV4 gäller i 7 dagar |
| IAM-rollsession (STS AssumeRole) | Tills sessionen upphör, 1 timme som standard |
| EC2-instansprofil | Tills rolluppgifterna roteras, som mest ungefär 6 timmar |
| ECS-uppgiftsroll | Tills uppgiftens uppgifter roteras, oftast var 1:a till 6:e timme |
| Uppgifter som återkallats eller tagits bort | Slutar direkt, oavsett vad X-Amz-Expires säger |
| S3-konsolen | Du väljer mellan 1 minut och 12 timmar |
Det förklarar den vanligaste överraskningen: du ber om 7 dagar från en Lambda-funktion eller en EC2-instans och länken dör efter en timme eller några timmar. URL:en lever bara lika länge som uppgifterna bakom den. Om du behöver långa länkar, signera med en dedikerad IAM-användare som bara har läsåtkomst till den bucketen.
S3 kontrollerar giltigheten när en förfrågan startar. En stor nedladdning som börjar en sekund före tidsgränsen slutförs normalt, men ett nytt försök efter tidsgränsen misslyckas med AccessDenied och meddelandet “Request has expired”. Att be om mer än 604 800 sekunder avvisas direkt.
Så skapar du en presignerad URL
AWS CLI
aws s3 presign s3://my-bucket/reports/q3.pdf --expires-in 3600
Kommandot signerar en URL för nedladdning (GET). Standard är 3 600 sekunder och max 604 800. Nyare versioner av CLI:t använder alltid SigV4, så se till att en region är konfigurerad. För uppladdnings-URL:er behöver du en SDK.
Python (boto3)
import boto3
from botocore.config import Config
s3 = boto3.client('s3', region_name='eu-west-1', config=Config(signature_version='s3v4'))
url = s3.generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': 'my-bucket',
'Key': 'reports/q3.pdf',
'ResponseContentDisposition': 'attachment; filename="q3.pdf"',
},
ExpiresIn=3600,
)
Ange signature_version='s3v4' uttryckligen. Boto3-referensen varnar för att den av bakåtkompatibilitetsskäl annars kan signera med den äldre Signature Version 2 i regioner som fortfarande accepterar den, vilket tyst tar bort vissa parametrar och headers som Range. ResponseContentDisposition är valfri: den gör att webbläsaren sparar filen med ett snyggt namn i stället för att öppna den direkt.
JavaScript (AWS SDK v3)
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
const client = new S3Client({ region: 'eu-west-1' })
const url = await getSignedUrl(
client,
new GetObjectCommand({ Bucket: 'my-bucket', Key: 'reports/q3.pdf' }),
{ expiresIn: 3600 }
)
Om du utelämnar expiresIn använder presignern för JavaScript 900 sekunder (15 minuter).
Presignerade URL:er för uppladdning (PUT)
Samma idé fungerar åt andra hållet. Du signerar en PutObject för en nyckel och den som har URL:en kan skriva det objektet. Filen går direkt från deras enhet till bucketen och din server hanterar aldrig byten. Om ett objekt med den nyckeln redan finns ersätts det.
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
const client = new S3Client({ region: 'eu-west-1' })
const url = await getSignedUrl(
client,
new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'incoming/brief.pdf',
ContentType: 'application/pdf',
}),
{ expiresIn: 900, signableHeaders: new Set(['content-type']) }
)
await fetch(url, {
method: 'PUT',
headers: { 'Content-Type': 'application/pdf' },
body: file,
})
Att lägga till content-type i signableHeaders knyter URL:en till den typen, så en uppladdning med en annan Content-Type avvisas. I boto3 är motsvarigheten generate_presigned_url('put_object', Params={'Bucket': ..., 'Key': ..., 'ContentType': 'application/pdf'}), och klienten måste skicka samma header.
Tre saker att kontrollera innan du laddar upp från en webbläsare:
- CORS. Bucketen behöver en CORS-regel som tillåter din origin och metoden
PUT. För multipart-uppladdningar måste den också exponera headernETag, eftersom webbläsaren måste läsa den från varje del. - Fast nyckel. Skapa en unik nyckel på servern (till exempel med ett UUID-prefix) så att en besökare inte kan skriva över någon annans fil.
- Kontrollsummor. Aktuella AWS SDK:er lägger som standard till en CRC-kontrollsumma vid uppladdningar. Om presignerade uppladdningar misslyckas mot en S3-kompatibel leverantör med signatur- eller kontrollsummefel, ställ in
requestChecksumCalculation: 'WHEN_REQUIRED'på klienten.
Presignerad POST är en separat mekanism för vanliga HTML-formulär, med en policy som kan begränsa storlek och innehållstyp. Alla S3-kompatibla leverantörer stöder den inte (R2 gör det inte), så presignerad PUT är det mer portabla valet.
Stora filer: presignerade multipart-uppladdningar
En enskild PUT till S3 är begränsad till 5 GB, och AWS föreslår multipart från ungefär 100 MB. Multipart delar upp filen i upp till 10 000 delar, var och en från 5 MiB till 5 GiB utom den sista, som laddas upp oberoende av varandra, parallellt och med nya försök per del. Presignering fungerar per del: servern startar uppladdningen, signerar en UploadPart-URL per del, webbläsaren skickar varje bit och rapporterar tillbaka dess ETag, och servern slutför uppladdningen.
import {
CreateMultipartUploadCommand,
UploadPartCommand,
CompleteMultipartUploadCommand,
} from '@aws-sdk/client-s3'
const { UploadId } = await client.send(
new CreateMultipartUploadCommand({ Bucket: 'my-bucket', Key: 'video/raw.mov' })
)
const partUrl = await getSignedUrl(
client,
new UploadPartCommand({ Bucket: 'my-bucket', Key: 'video/raw.mov', UploadId, PartNumber: 1 }),
{ expiresIn: 3600 }
)
await client.send(
new CompleteMultipartUploadCommand({
Bucket: 'my-bucket',
Key: 'video/raw.mov',
UploadId,
MultipartUpload: { Parts: [{ PartNumber: 1, ETag: etagFromPartResponse }] },
})
)
Lägg till en livscykelregel som avbryter ofullständiga multipart-uppladdningar efter några dagar, annars fortsätter övergivna delar att ta upp debiterbar lagring.
Presignerade URL:er i R2, B2, Spaces och Wasabi
Leverantörer som implementerar S3-API:et med SigV4 accepterar samma kod: du byter bara endpoint, region och nycklar. Detaljerna skiljer sig, så kontrollera leverantörens dokumentation:
- Cloudflare R2 stöder presignerade
GET,HEAD,PUTochDELETE, med en giltighet från 1 sekund till 7 dagar. Den stöder inte presigneradPOST, och presignerade URL:er fungerar bara på S3-API-domänen (<ACCOUNT_ID>.r2.cloudflarestorage.com), inte på egna domäner. Användregion: 'auto'. - Backblaze B2 anger att dess S3-kompatibla API stöder presignerade URL:er som skapats med AWS CLI eller SDK:erna.
- DigitalOcean Spaces och Wasabi fungerar med samma SDK-anrop riktade mot deras endpoints.
För priser hos varje leverantör, se jämförelsen av S3, R2, Spaces, Wasabi och B2.
Vanliga fel med presignerade URL:er och hur du åtgärdar dem
| Fel | Vanlig orsak | Åtgärd |
|---|---|---|
SignatureDoesNotMatch | Metod, headers eller frågesträng skiljer sig från det som signerades; klockan går fel | Skicka samma Content-Type och headers; synkronisera klockan med NTP |
AccessDenied “Request has expired” | URL:en har passerat X-Amz-Date + X-Amz-Expires | Skapa en ny URL; korta tiden mellan signering och användning |
| URL:en går ut tidigare än begärt | Signerad med tillfälliga uppgifter (roll, EC2, ECS, Lambda) | Signera med uppgifter som lever lika länge som länken måste |
ExpiredToken | STS-sessionen bakom X-Amz-Security-Token har upphört | Förnya uppgifterna innan du signerar |
403 AccessDenied på en ny URL | Signeraren saknar s3:GetObject eller s3:PutObject, eller en policy nekar | Ge behörigheten till den signerande identiteten; kontrollera bucketpolicyer |
AuthorizationQueryParametersError | Giltighet över 604 800 sekunder eller ett felaktigt credential-omfång | Håll X-Amz-Expires på 7 dagar eller mindre; signera i bucketens region |
| Webbläsaren blockeras av CORS | Ingen CORS-regel för din origin och metod på bucketen | Lägg till en CORS-regel med din origin, GET/PUT och exponerad ETag |
AccessDenied med HeadersNotSigned | Range signerades men If-Range skickades osignerad | Lägg till If-Range bland de signerade headers |
Företagsproxyer som skriver om headers eller frågesträngar förstör också signaturer. Om en URL fungerar från ett nätverk men inte från ett annat, testa utan proxyn.
Bästa praxis för säkerhet
AWS kallar presignerade URL:er för bearer tokens och rekommenderar att de skyddas. I praktiken:
- Håll dem korta. Minuter för uppladdningar och känsliga filer, timmar för vanliga nedladdningar. Skapa en ny när någon behöver filen igen.
- Signera med en snäv identitet. En dedikerad IAM-användare eller roll som bara kan läsa (eller bara skriva) det aktuella prefixet begränsar skadan om en länk läcker.
- Lägg till skyddsräcken i bucketpolicyn. Villkoret
s3:signatureAgeavvisar signaturer som är äldre än en viss ålder, ochaws:SourceIpbegränsar vilka nätverk som kan använda dem. - Logga dem inte. Fullständiga presignerade URL:er i applikationsloggar, analysverktyg eller chatthistorik är fungerande inloggningsuppgifter tills de går ut.
- Planera för det de saknar. Det finns inget lösenord, ingen räkning av nedladdningar och ingen återkallelse per länk, så sätt en applikation framför när du behöver det.
För delningssidan på djupet, med alternativ som lägger till de kontrollerna, se hur du delar S3-filer utan att göra bucketen publik.
Så använder Nubbo presignerade URL:er
Nubbo är byggt på det här mönstret. När du laddar upp i utforskaren signerar servern en PUT (eller, från 100 MB, en multipart-uppladdning med tre delar parallellt) och din webbläsare skickar byten direkt till din bucket. Nedladdningar av enskilda filer använder presignerade GET-URL:er som gäller i en timme. Dina åtkomstnycklar lagras krypterade med AES-256-GCM och används bara på servern för att signera.
Delningslänkar lägger till det som råa presignerade URL:er saknar: valfritt lösenord, utgångsdatum och nedladdningsgräns som Nubbo kontrollerar innan den delar ut en kortlivad URL, och du kan inaktivera en länk när som helst. ZIP-nedladdningar av flera filer sätts ihop i din webbläsare, som laddar ner varje fil direkt från din bucket: Nubbo ser aldrig innehållet. Ett ärligt undantag: miniatyrer skrivs till din egen bucket under .nubbo-thumbs/. Det fungerar likadant med Amazon S3, Cloudflare R2, DigitalOcean Spaces, Wasabi, Backblaze B2 och publika S3-kompatibla endpoints.
Vanliga frågor
Vad är en presignerad URL i S3?
Det är en vanlig HTTPS-länk till ett objekt i en privat bucket med en signatur tillagd i frågesträngen. Den som har länken kan utföra den enda operation som den signerades för, oftast en nedladdning (GET) eller en uppladdning (PUT), tills den går ut. Bucketen förblir privat och den som använder länken behöver inga AWS-uppgifter.
Hur länge kan en presignerad URL i S3 som längst gälla?
Sju dagar (604 800 sekunder) när du signerar med Signature Version 4 och långlivade nycklar för en IAM-användare. En URL som signerats med tillfälliga uppgifter, till exempel en antagen roll eller en EC2-instansprofil, slutar fungera när de uppgifterna går ut, även om du bad om längre tid. I S3-konsolen kan du välja mellan 1 minut och 12 timmar.
Vad betyder X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders och X-Amz-Signature?
De är autentiseringsparametrarna i SigV4. Algorithm är signeringsmetoden (AWS4-HMAC-SHA256), Credential är ditt åtkomstnyckel-ID plus datum, region och tjänst, Date är när URL:en signerades, Expires är hur många sekunder den gäller, SignedHeaders listar headers som omfattas av signaturen och Signature är själva signaturen. X-Amz-Security-Token finns bara med när URL:en signerades med tillfälliga uppgifter.
Kan jag återkalla en presignerad URL i S3 innan den går ut?
Inte en och en. En presignerad URL slutar fungera i förtid bara när uppgifterna som signerade den återkallas, tas bort eller inaktiveras, eller när en bucketpolicy nekar förfrågan. Om du behöver kunna avbryta enskilda länkar, sätt en applikation framför som bara delar ut kortlivade URL:er efter sina egna kontroller.
Är presignerade URL:er i S3 säkra?
Signaturen kan inte förfalskas eller ändras, och bucketen förblir privat. Men AWS beskriver presignerade URL:er som bearer tokens: vem som helst som får tag i länken kan använda den, hur många gånger som helst, tills den går ut. Håll giltighetstiderna korta, använd HTTPS och undvik att publicera länkarna där de kan kopieras.
Fungerar presignerade URL:er med Cloudflare R2, Backblaze B2 eller Wasabi?
Leverantörer som implementerar S3-API:et med Signature Version 4 stöder dem i regel, och du använder samma SDK-anrop med leverantörens endpoint. Cloudflare R2 stöder till exempel presignerade GET, HEAD, PUT och DELETE med en giltighet från 1 sekund till 7 dagar, men inte uppladdning via POST-formulär och inte egna domäner.
Varför returnerar min presignerade URL SignatureDoesNotMatch?
AWS listar tre vanliga orsaker: en dator vars klocka går fel, en proxy som ändrar headers eller frågesträngen, och en förfrågan vars metod, headers eller parametrar skiljer sig från dem som signerades. Vid uppladdningar är den vanliga boven att man skickar en annan Content-Type än den som användes när URL:en skapades.
Källor
Priser och gränser kommer från de officiella sidorna nedan. Leverantörerna ändrar dem, så kontrollera innan du bestämmer dig.
- Amazon S3: ladda ner och upp objekt med presignerade URL:er
- AWS IAM: autentiseringsmetoder (frågeparametrar i SigV4)
- Amazon S3 API: autentisera förfrågningar med frågeparametrar (SigV4)
- AWS CLI-referens: s3 presign
- Boto3-referens: generate_presigned_url
- AWS SDK for JavaScript v3: @aws-sdk/s3-request-presigner
- Amazon S3: gränser för multipart-uppladdning
- AWS SDKs and Tools: dataintegritetsskydd för Amazon S3
- Cloudflare R2: presignerade URL:er
- Backblaze: stöder B2:s S3-kompatibla API presignerade URL:er?