Straipsnis

S3 presigned URL: kas tai, kaip veikia, galiojimo ribos ir kodo pavyzdžiai

Kas yra S3 presigned URL, ką reiškia kiekvienas X-Amz parametras, 7 dienų galiojimo riba, įkėlimo ir atsisiuntimo kodas (CLI, boto3, JS) ir klaidos.

S3 presigned URL yra laikina nuoroda į vieną objektą privačiame bucket. Jos užklausos eilutėje yra parašas, todėl ją turintis asmuo gali atsisiųsti (ar įkelti) tą objektą be AWS prisijungimo duomenų, kol nuoroda nustos galioti, o bucket niekada netampa viešas. Ją sukuriate savo raktais, savo kode ar per AWS CLI, ir ji gali galioti nuo 1 sekundės iki 7 dienų. Šiame vadove aptariama, kaip tai veikia, ką reiškia kiekvienas X-Amz-* parametras, kiek ilgai nuoroda gali galioti, atsisiuntimų ir įkėlimų kodas ir klaidos, su kuriomis greičiausiai susidursite. Ribos paimtos iš AWS ir Cloudflare dokumentacijos, 2026 m. spalio mėnesio būklė.

S3 presigned URL trumpai

KlausimasAtsakymas
Ką ji suteikia?Vieną operaciją (GET, PUT, HEAD, DELETE…) su vienu objektu
Didžiausias galiojimas7 dienos (604 800 sekundžių) su SigV4 ir IAM vartotojo raktais
Galiojimas su laikinais raktaisBaigiasi, kai baigiasi vaidmens sesija ar STS duomenys, kas įvyksta anksčiau
S3 konsolės intervalasNuo 1 minutės iki 12 valandų
Numatytasis galiojimas3 600 s AWS CLI ir boto3, 900 s JavaScript v3 presigner
Ar galima naudoti kelis kartus?Taip, kiek tik kas nori, kol ji nustos galioti
Ar galima atšaukti vieną URL?Ne, tik atšaukus pasirašymo duomenis arba uždraudus politikoje
Ar jos sukūrimas kreipiasi į S3?Ne, parašas apskaičiuojamas vietoje

Kaip veikia presigned URL

  1. Jūsų kodas (ar CLI) paima bucket, objekto raktą, HTTP metodą ir galiojimo laiką.
  2. SDK pasirašo šias reikšmes jūsų slaptuoju prieigos raktu naudodamas AWS Signature Version 4. Šiame etape į S3 nieko nesiunčiama.
  3. Gautą URL kam nors perduodate: naršyklei, kolegai, mobiliajai programai.
  4. Kai jis panaudojamas, S3 iš naujo apskaičiuoja parašą su slaptuoju raktu, priklausančiu URL nurodytam prieigos raktui. Jei jis sutampa, URL dar galioja, o pasirašiusysis turi teisę atlikti tą operaciją, užklausa įvykdoma.

URL turi jį pasirašiusiojo teises. AWS tai aiškiai nurodo: jei URL sugeneravęs IAM vartotojas ar vaidmuo negali skaityti objekto, URL grąžina 403, kad ir koks galiojantis būtų parašas.

Ką reiškia X-Amz parametrai

SigV4 presigned URL atrodo taip (pridėti eilučių lūžiai):

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
ParametrasReikšmė
X-Amz-AlgorithmPasirašymo algoritmas: AWS4-HMAC-SHA256 SigV4 atveju
X-Amz-CredentialPrieigos rakto ID plius apimtis: <key-id>/<YYYYMMDD>/<region>/s3/aws4_request
X-Amz-DateKada URL pasirašytas, UTC laiku, yyyyMMddTHHmmssZ
X-Amz-ExpiresKiek sekundžių URL galioja po X-Amz-Date, nuo 1 iki 604800
X-Amz-SignedHeadersParašo apimamos antraštės, visada bent host
X-Amz-SignatureParašas, 64 šešioliktainiai simboliai
X-Amz-Security-TokenYra tik tada, kai URL pasirašytas laikinais prisijungimo duomenimis (STS, vaidmenys, EC2, ECS, SSO)

Pakeiskite bet kurią pasirašytą dalį (raktą, metodą, galiojimą ar pasirašytą antraštę), ir parašas nebesutaps. Atkreipkite dėmesį ir į tai, ką URL atskleidžia atviru tekstu: bucket pavadinimą, visą objekto raktą ir jūsų prieigos rakto ID. Slaptojo rakto URL niekada nėra.

Kiek ilgai galioja presigned URL

Riba priklauso nuo jį pasirašančių prisijungimo duomenų:

Pasirašyta suDidžiausias galiojimas
IAM vartotojo prieigos raktais (SigV4)7 dienos, nes pats SigV4 pasirašymo raktas galioja 7 dienas
IAM vaidmens sesija (STS AssumeRole)Kol baigiasi sesija, pagal numatytuosius nustatymus 1 valanda
EC2 instance profileKol pasikeičia vaidmens duomenys, daugiausia apie 6 valandas
ECS užduoties vaidmuoKol pasikeičia užduoties duomenys, paprastai kas nuo 1 iki 6 valandų
Bet kokie atšaukti ar ištrinti duomenysNustoja veikti iš karto, kad ir ką rodytų X-Amz-Expires
S3 konsolėPasirenkate nuo 1 minutės iki 12 valandų

Tai paaiškina dažniausią staigmeną: iš Lambda funkcijos ar EC2 egzemplioriaus prašote 7 dienų, o nuoroda nustoja veikti po valandos ar kelių. URL galioja tik tiek, kiek už jo stovintys prisijungimo duomenys. Jei reikia ilgai galiojančių nuorodų, pasirašykite specialiu IAM vartotoju, kuris turi skaitymo prieigą tik prie to bucket.

S3 galiojimą tikrina, kai užklausa prasideda. Didelis atsisiuntimas, prasidėjęs sekundę prieš terminą, baigiamas įprastai, bet pakartotinis bandymas po termino nepavyksta su AccessDenied ir pranešimu „Request has expired“. Prašymas, viršijantis 604 800 sekundžių, atmetamas iš karto.

Kaip sugeneruoti presigned URL

AWS CLI

aws s3 presign s3://my-bucket/reports/q3.pdf --expires-in 3600

Komanda pasirašo atsisiuntimo (GET) URL. Numatytoji reikšmė 3 600 sekundžių, didžiausia 604 800. Naujesnės CLI versijos visada naudoja SigV4, todėl įsitikinkite, kad sukonfigūruotas regionas. Įkėlimo URL reikia 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,
)

Aiškiai nustatykite signature_version='s3v4'. Boto3 žinyne įspėjama, kad dėl atgalinio suderinamumo kitaip jis gali pasirašyti senesniu Signature Version 2 regionuose, kurie jį dar priima, o tai tyliai pašalina kai kuriuos parametrus ir antraštes, pavyzdžiui, Range. ResponseContentDisposition neprivalomas: jis priverčia naršyklę išsaugoti failą su tvarkingu pavadinimu, užuot atidarius jį naršyklėje.

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 }
)

Jei praleisite expiresIn, JavaScript presigner naudoja 900 sekundžių (15 minučių).

Presigned įkėlimo URL (PUT)

Ta pati idėja veikia ir priešinga kryptimi. Pasirašote PutObject vienam raktui, ir kas turi URL, gali įrašyti tą objektą. Failas keliauja tiesiai iš jų įrenginio į bucket, o jūsų serveris baitų niekada neapdoroja. Jei objektas su tuo raktu jau yra, jis pakeičiamas.

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,
})

Pridėjus content-type prie signableHeaders, URL susiejamas su tuo tipu, todėl įkėlimas su kitu Content-Type atmetamas. Boto3 atitikmuo yra generate_presigned_url('put_object', Params={'Bucket': ..., 'Key': ..., 'ContentType': 'application/pdf'}), o klientas turi siųsti tą pačią antraštę.

Trys dalykai, kuriuos reikia patikrinti prieš įkeliant iš naršyklės:

  • CORS. Bucket reikia CORS taisyklės, leidžiančios jūsų kilmę ir PUT metodą. Multipart įkėlimams ji taip pat turi atskleisti ETag antraštę, nes naršyklė turi ją perskaityti iš kiekvienos dalies.
  • Fiksuotas raktas. Unikalų raktą generuokite serveryje (pavyzdžiui, su UUID prefiksu), kad lankytojas negalėtų perrašyti kito žmogaus failo.
  • Kontrolinės sumos. Dabartiniai AWS SDK pagal numatytuosius nustatymus prie įkėlimų prideda CRC kontrolinę sumą. Jei presigned įkėlimai į S3 suderinamą teikėją nepavyksta dėl parašo ar kontrolinės sumos klaidų, klientui nustatykite requestChecksumCalculation: 'WHEN_REQUIRED'.

Presigned POST yra atskiras mechanizmas paprastoms HTML formoms, su politika, kuri gali riboti dydį ir turinio tipą. Ne kiekvienas S3 suderinamas teikėjas jį palaiko (R2 nepalaiko), todėl presigned PUT yra universalesnis pasirinkimas.

Dideli failai: presigned multipart įkėlimai

Pavienis PUT į S3 ribojamas 5 GB, o AWS siūlo multipart nuo maždaug 100 MB. Multipart padalija failą į iki 10 000 dalių, kiekviena nuo 5 MiB iki 5 GiB, išskyrus paskutinę, kurios įkeliamos nepriklausomai, lygiagrečiai ir su pakartojimais kiekvienai daliai. Pasirašymas veikia kiekvienai daliai: serveris pradeda įkėlimą, kiekvienai daliai pasirašo po vieną UploadPart URL, naršyklė siunčia kiekvieną gabalą ir grąžina jo ETag, o serveris užbaigia įkėlimą.

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 }] },
  })
)

Pridėkite gyvavimo ciklo taisyklę, kuri po kelių dienų nutraukia nebaigtus multipart įkėlimus, kitaip apleistos dalys toliau užims apmokestinamą vietą.

Presigned URL R2, B2, Spaces ir Wasabi

Teikėjai, įgyvendinantys S3 API su SigV4, priima tą patį kodą: pakeičiate tik endpoint, regioną ir raktus. Detalės skiriasi, todėl pasitikrinkite teikėjo dokumentaciją:

  • Cloudflare R2 palaiko presigned GET, HEAD, PUT ir DELETE, su galiojimu nuo 1 sekundės iki 7 dienų. Jis nepalaiko presigned POST, o presigned URL veikia tik S3 API domene (<ACCOUNT_ID>.r2.cloudflarestorage.com), ne pasirinktiniuose domenuose. Naudokite region: 'auto'.
  • Backblaze B2 nurodo, kad jo S3 suderinama API palaiko presigned URL, sugeneruotus su AWS CLI ar SDK.
  • DigitalOcean Spaces ir Wasabi veikia su tais pačiais SDK kvietimais, nukreiptais į jų endpoint.

Kiekvieno teikėjo kainas rasite S3, R2, Spaces, Wasabi ir B2 palyginime.

Dažnos presigned URL klaidos ir kaip jas ištaisyti

KlaidaĮprasta priežastisSprendimas
SignatureDoesNotMatchMetodas, antraštės ar užklausa skiriasi nuo pasirašytųjų; nesinchronizuotas laikrodisSiųskite tą patį Content-Type ir antraštes; sinchronizuokite laikrodį su NTP
AccessDenied „Request has expired“URL galiojimas pasibaigė po X-Amz-Date + X-Amz-ExpiresSugeneruokite naują URL; sutrumpinkite laiką tarp pasirašymo ir naudojimo
URL nustoja galioti anksčiau nei prašytaPasirašyta laikinais duomenimis (vaidmuo, EC2, ECS, Lambda)Pasirašykite duomenimis, kurie galioja tiek, kiek turi galioti nuoroda
ExpiredTokenBaigėsi STS sesija už X-Amz-Security-TokenAtnaujinkite prisijungimo duomenis prieš pasirašydami
403 AccessDenied naujam URLPasirašiusysis neturi s3:GetObject ar s3:PutObject arba tai draudžia politikaSuteikite teisę pasirašančiam subjektui; patikrinkite bucket politikas
AuthorizationQueryParametersErrorGaliojimas virš 604 800 sekundžių arba netinkama duomenų apimtisLaikykite X-Amz-Expires ne daugiau 7 dienų; pasirašykite bucket regione
Naršyklę blokuoja CORSBucket neturi CORS taisyklės jūsų kilmei ir metoduiPridėkite CORS taisyklę su savo kilme, GET/PUT ir atskleistu ETag
AccessDenied su HeadersNotSignedRange pasirašyta, bet If-Range išsiųsta nepasirašytaPridėkite If-Range prie pasirašytų antraščių

Įmonių tarpiniai serveriai, perrašantys antraštes ar užklausos eilutes, taip pat sugadina parašus. Jei URL veikia iš vieno tinklo, bet ne iš kito, išbandykite be tarpinio serverio.

Saugumo gerosios praktikos

AWS presigned URL vadina bearer tokens ir rekomenduoja juos saugoti. Praktiškai:

  • Laikykite juos trumpus. Minutės įkėlimams ir jautriems failams, valandos įprastiems atsisiuntimams. Kai kam nors vėl reikia failo, sugeneruokite naują.
  • Pasirašykite siaura tapatybe. Specialus IAM vartotojas ar vaidmuo, kuris gali tik skaityti (ar tik rašyti) atitinkamą prefiksą, apriboja žalą, jei nuoroda nutekės.
  • Pridėkite apsaugas bucket politikoje. Sąlyga s3:signatureAge atmeta parašus, senesnius nei nustatytas amžius, o aws:SourceIp riboja, kurie tinklai gali juos naudoti.
  • Neregistruokite jų žurnaluose. Pilni presigned URL programų žurnaluose, analitikoje ar pokalbių istorijoje yra veikiantys prisijungimo duomenys, kol nenustos galioti.
  • Įvertinkite, ko jiems trūksta. Nėra slaptažodžio, atsisiuntimų skaičiaus ir atskiros nuorodos atšaukimo, todėl, kai to reikia, priekyje pastatykite programą.

Išsamiau apie bendrinimą, su variantais, kurie prideda šias kontrolės priemones, skaitykite straipsnyje kaip bendrinti S3 failus nepadarant bucket viešo.

Kaip Nubbo naudoja presigned URL

Nubbo sukurta šiuo principu. Kai įkeliate naršyklėje, serveris pasirašo PUT (arba, nuo 100 MB, multipart įkėlimą su trimis lygiagrečiomis dalimis), o jūsų naršyklė siunčia baitus tiesiai į jūsų bucket. Pavienių failų atsisiuntimai naudoja presigned GET URL, galiojančius vieną valandą. Jūsų prieigos raktai saugomi užšifruoti AES-256-GCM ir naudojami tik serveryje pasirašymui.

Bendrinimo nuorodos prideda tai, ko trūksta paprastiems presigned URL: pasirinktinį slaptažodį, galiojimo datą ir atsisiuntimų limitą, kuriuos Nubbo patikrina prieš išduodama trumpalaikį URL, o nuorodą galite bet kada išjungti. Kelių failų ZIP atsisiuntimai sudaromi jūsų naršyklėje, kuri kiekvieną failą atsisiunčia tiesiai iš jūsų bucket: Nubbo niekada nemato turinio. Viena sąžininga išimtis: miniatiūros įrašomos į jūsų pačių bucket aplanke .nubbo-thumbs/. Tai veikia vienodai su Amazon S3, Cloudflare R2, DigitalOcean Spaces, Wasabi, Backblaze B2 ir viešais S3 suderinamais endpoint.

Dažnai užduodami klausimai

Kas yra presigned URL S3?

Tai įprasta HTTPS nuoroda į vieną objektą privačiame bucket su parašu, pridėtu prie užklausos eilutės. Kas turi nuorodą, gali atlikti vienintelę operaciją, kuriai ji pasirašyta, dažniausiai atsisiuntimą (GET) ar įkėlimą (PUT), kol ji nustos galioti. Bucket lieka privatus, o nuorodą naudojančiam žmogui nereikia AWS prisijungimo duomenų.

Koks didžiausias S3 presigned URL galiojimo laikas?

Septynios dienos (604 800 sekundžių), kai pasirašote su Signature Version 4 ir ilgalaikiais IAM vartotojo raktais. URL, pasirašytas laikinais prisijungimo duomenimis, pavyzdžiui, prisiimtu vaidmeniu ar EC2 instance profile, nustoja veikti, kai baigiasi tų duomenų galiojimas, net jei prašėte ilgiau. S3 konsolėje galite rinktis nuo 1 minutės iki 12 valandų.

Ką reiškia X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders ir X-Amz-Signature?

Tai SigV4 autentifikavimo parametrai. Algorithm yra pasirašymo metodas (AWS4-HMAC-SHA256), Credential yra jūsų prieigos rakto ID plius datos, regiono ir paslaugos apimtis, Date yra laikas, kada URL pasirašytas, Expires yra kiek sekundžių jis galioja, SignedHeaders išvardija parašo apimamas antraštes, o Signature yra pats parašas. X-Amz-Security-Token atsiranda tik tada, kai URL pasirašytas laikinais prisijungimo duomenimis.

Ar galiu atšaukti S3 presigned URL, kol jis dar galioja?

Ne po vieną. Presigned URL anksčiau nustoja veikti tik tada, kai jį pasirašę prisijungimo duomenys atšaukiami, ištrinami ar išjungiami arba kai bucket politika draudžia užklausą. Jei reikia atšaukti atskiras nuorodas, priekyje pastatykite programą, kuri trumpalaikius URL išduoda tik po savo patikrų.

Ar S3 presigned URL saugūs?

Parašo negalima suklastoti ar pakeisti, o bucket lieka privatus. Tačiau AWS presigned URL apibūdina kaip bearer tokens: kiekvienas, gavęs nuorodą, gali ją naudoti kiek tik nori kartų, kol ji nustos galioti. Galiojimo laiką laikykite trumpą, naudokite HTTPS ir nepublikuokite nuorodų ten, kur jas galima nukopijuoti.

Ar presigned URL veikia su Cloudflare R2, Backblaze B2 ar Wasabi?

Teikėjai, įgyvendinantys S3 API su Signature Version 4, paprastai juos palaiko, ir naudojate tuos pačius SDK kvietimus su teikėjo endpoint. Pavyzdžiui, Cloudflare R2 palaiko presigned GET, HEAD, PUT ir DELETE su galiojimu nuo 1 sekundės iki 7 dienų, bet nepalaiko POST formų įkėlimų ir pasirinktinių domenų.

Kodėl mano presigned URL grąžina SignatureDoesNotMatch?

AWS nurodo tris dažnas priežastis: nesinchronizuotas kompiuterio laikrodis, tarpinis serveris, keičiantis antraštes ar užklausos eilutę, ir užklausa, kurios metodas, antraštės ar parametrai skiriasi nuo pasirašytųjų. Įkėlimų atveju dažniausia kaltininkė yra kitokia Content-Type antraštė nei ta, kuri naudota generuojant URL.

Šaltiniai

Kainos ir ribos paimtos iš toliau nurodytų oficialių puslapių. Teikėjai jas keičia, todėl patikrinkite prieš apsispręsdami.