Skip to content

S3 suderinamumas

Naudokite AWS SDK failams įkelti, atsisiųsti ir tvarkyti IPFS Ninja platformoje su tuo pačiu kodu, kurį naudojate Amazon S3.

Galinis taškas

https://s3.ipfs.ninja

Kredencialai

S3 API autentifikacijai naudoja jūsų IPFS Ninja API raktą. Jūsų API raktas veikia ir kaip access key, ir kaip secret key.

Kaip gauti kredencialus

  1. Eikite į Dashboard > API Keys
  2. Spustelėkite Create API key ir suteikite pavadinimą (pvz., „S3 access“)
  3. Nedelsdami nukopijuokite visą raktą — jis rodomas tik vieną kartą ir vėliau negali būti atkurtas

Jūsų raktas atrodo taip:

bws_628bba35e9e0079d9ff9c392b1b55a7b
├──────────┘└──────────────────────────┘
 prefix (12 chars)    rest of key

Susiejimas su AWS kredencialais

AWS parametrasReikšmėPavyzdys
accessKeyIdPirmieji 12 jūsų API rakto simboliųbws_628bba35
secretAccessKeyVisas API raktas (visi 36 simboliai)bws_628bba35e9e0079d9ff9c392b1b55a7b
regionVisada us-east-1us-east-1

WARNING

Visas API raktas rodomas tik vieną kartą jį kuriant. Jei jį pametėte, ištrinkite raktą ir sukurkite naują iš API Keys puslapio.

Greita pradžia

javascript
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "https://s3.ipfs.ninja",
  credentials: {
    accessKeyId: "bws_628bba35",
    secretAccessKey: "bws_628bba35e9e0079d9ff9c392b1b55a7b"
  },
  region: "us-east-1",
  forcePathStyle: true
});

// Upload a file
const put = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "hello.json",
  Body: JSON.stringify({ hello: "IPFS" }),
  ContentType: "application/json"
}));

console.log("CID:", put.Metadata?.cid);
// CID: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

Bucket = aplankai

S3 bucket atitinka jūsų IPFS Ninja aplankus. Kai įkeliate failą į bucket, jis saugomas atitinkamame aplanke. Kai išsivardijate objektus bucket viduje, matote to aplanko failus.

S3 operacijaIPFS Ninja atitikmuo
CreateBucketSukurti naują aplanką
ListBucketsIšvardyti savo aplankus
DeleteBucketIštrinti aplanką ir visus jame esančius failus
PutObject į bucketĮkelti failą į aplanką
ListObjectsV2 bucket vidujeIšvardyti failus aplanke
javascript
import { ListBucketsCommand, CreateBucketCommand, PutObjectCommand } from "@aws-sdk/client-s3";

// Create a bucket (= create a folder)
await s3.send(new CreateBucketCommand({ Bucket: "nft-metadata" }));

// Upload a file into the folder
await s3.send(new PutObjectCommand({
  Bucket: "nft-metadata",      // ← folder name
  Key: "token-42.json",        // ← filename within the folder
  Body: JSON.stringify({ name: "My NFT #42" })
}));

// List buckets (= list your folders)
const { Buckets } = await s3.send(new ListBucketsCommand({}));
console.log(Buckets);
// [{ Name: "nft-metadata", CreationDate: "2026-04-13T..." }]

TIP

Aplankai, sukurti per S3 API, yra tie patys aplankai, matomi jūsų Dashboard. Failus galite tvarkyti per S3 API, REST API arba internetinę sąsają — visi jie naudoja tą pačią aplankų sistemą.

INFO

Skirtingai nei Amazon S3, IPFS Ninja aplankai pagal numatytuosius nustatymus yra plokšti. Norėdami sukurti įdėtines struktūras, naudokite REST API aplankų galinius taškus su parentFolderId. Iš S3 API naudokite rakto prefiksus (pvz., images/photo.png), kad tvarkytumėte turinį aplanko viduje.

Bucket pavadinimai yra globaliai unikalūs

Bucket pavadinimai gyvena globaliame vardų pavadinimų erdvėje tarp visų klientų, atitinkant AWS S3 semantiką. Tai reiškia:

  • Pirmasis naudotojas, sukūręs bucket su tam tikru pavadinimu, užsiima tą pavadinimą globaliai.
  • Vėlesni CreateBucket iškvietimai su tuo pačiu pavadinimu iš bet kurios paskyros grąžina BucketAlreadyExists (409).
  • Jei bandote iš naujo sukurti savo paties bucket, gaunate BucketAlreadyOwnedByYou (409).
  • Jūsų aplanko pavadinimas prietaisų skydelyje yra priskirtas paskyrai ir vis tiek gali būti bet koks — tik S3 matomas bucket pavadinimas eina per globalią vardų erdvę.

Jei norimas pavadinimas užimtas, pasirinkite kitokio apimtingumo pavadinimą (myapp-photos-2026, acme-nft-metadata) — tokia pati konvencija, kokią naudotumėte Amazon S3.

Palaikomos operacijos

PutObject

Įkelkite failą į IPFS. Failas prisegamas, patikrinamas dėl saugumo, o CID grąžinamas ETag ir x-amz-meta-cid antraštėse.

Norėdami importuoti CAR failą vietoj įprasto failo, pridėkite x-amz-meta-import: car metaduomenų antraštę. Žiūrėkite CAR importas daugiau informacijos.

javascript
import { PutObjectCommand } from "@aws-sdk/client-s3";
import fs from "fs";

const result = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "photo.png",
  Body: fs.readFileSync("photo.png"),
  ContentType: "image/png"
}));

console.log("CID:", result.ETag);
bash
# curl equivalent
curl -X PUT "https://s3.ipfs.ninja/my-project/photo.png" \
  --data-binary @photo.png \
  -H "Content-Type: image/png" \
  --aws-sigv4 "aws:amz:us-east-1:s3" \
  --user "bws_628bba35:bws_628bba35e9e0079d9ff9c392b1b55a7b"

GetObject

Atsisiųskite failą pagal jo raktą (failo pavadinimą) arba CID.

javascript
import { GetObjectCommand } from "@aws-sdk/client-s3";

const result = await s3.send(new GetObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

const body = await result.Body.transformToByteArray();
console.log("Size:", body.length);
console.log("CID:", result.Metadata?.cid);

HeadObject

Gaukite failo metaduomenis neatsisiunčiant turinio.

javascript
import { HeadObjectCommand } from "@aws-sdk/client-s3";

const head = await s3.send(new HeadObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

console.log("Size:", head.ContentLength);
console.log("Type:", head.ContentType);
console.log("CID:", head.Metadata?.cid);

DeleteObject

Atsekite failą nuo IPFS ir ištrinkite jį iš savo paskyros.

javascript
import { DeleteObjectCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

ListObjectsV2

Išvardykite failus bucket viduje su pasirenkamu prefikso filtru ir puslapiavimu.

javascript
import { ListObjectsV2Command } from "@aws-sdk/client-s3";

const list = await s3.send(new ListObjectsV2Command({
  Bucket: "my-project",
  Prefix: "images/",
  MaxKeys: 100
}));

for (const obj of list.Contents ?? []) {
  console.log(obj.Key, obj.Size, obj.ETag); // ETag = CID
}

Multipart Upload

Įkelkite didelius failus (iki 5 GB) naudodami daugiadalį įkėlimą. AWS SDK tai atlieka automatiškai:

javascript
import { Upload } from "@aws-sdk/lib-storage";
import fs from "fs";

const upload = new Upload({
  client: s3,
  params: {
    Bucket: "my-project",
    Key: "large-dataset.tar.gz",
    Body: fs.createReadStream("large-dataset.tar.gz"),
    ContentType: "application/gzip"
  },
  partSize: 10 * 1024 * 1024, // 10 MB per part
});

upload.on("httpUploadProgress", (progress) => {
  console.log(`Uploaded ${progress.loaded} of ${progress.total} bytes`);
});

const result = await upload.done();
console.log("CID:", result.ETag);

Arba valdykite dalis rankiniu būdu:

javascript
import {
  CreateMultipartUploadCommand,
  UploadPartCommand,
  CompleteMultipartUploadCommand
} from "@aws-sdk/client-s3";

// 1. Start
const { UploadId } = await s3.send(new CreateMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin"
}));

// 2. Upload parts
const part1 = await s3.send(new UploadPartCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  PartNumber: 1,
  Body: chunk1
}));

// 3. Complete
const result = await s3.send(new CompleteMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  MultipartUpload: {
    Parts: [{ PartNumber: 1, ETag: part1.ETag }]
  }
}));

Python pavyzdys

python
import boto3

s3 = boto3.client(
    "s3",
    endpoint_url="https://s3.ipfs.ninja",
    aws_access_key_id="bws_628bba35",
    aws_secret_access_key="bws_628bba35e9e0079d9ff9c392b1b55a7b",
    region_name="us-east-1"
)

# Upload
s3.put_object(
    Bucket="my-project",
    Key="data.json",
    Body=b'{"hello": "IPFS"}',
    ContentType="application/json"
)

# List files
response = s3.list_objects_v2(Bucket="my-project")
for obj in response.get("Contents", []):
    print(obj["Key"], obj["Size"])

# Download
result = s3.get_object(Bucket="my-project", Key="data.json")
print(result["Body"].read())

Go pavyzdys

go
package main

import (
    "context"
    "fmt"
    "strings"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    client := s3.New(s3.Options{
        BaseEndpoint: aws.String("https://s3.ipfs.ninja"),
        Region:       "us-east-1",
        Credentials:  credentials.NewStaticCredentialsProvider("bws_628bba35", "bws_628bba35e9e0...", ""),
        UsePathStyle: true,
    })

    _, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
        Bucket:      aws.String("my-project"),
        Key:         aws.String("hello.txt"),
        Body:        strings.NewReader("Hello, IPFS!"),
        ContentType: aws.String("text/plain"),
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("Uploaded!")
}

Konfigūruoti CORS (naršyklės SDK prieiga)

Jei S3 API kviečiate tiesiogiai iš naršyklės JavaScript (SPA, piniginės programa, prietaisų skydelio įrankis), pirmiausia turite sukonfigūruoti CORS ant bucket. Kitaip naršyklės blokuoja preflight užklausą, ir jūsų įkėlimai nepavyksta su klaida No 'Access-Control-Allow-Origin' header is present.

Tokia pati struktūra kaip AWS S3 — PutBucketCors / GetBucketCors / DeleteBucketCors subresursai:

PutBucketCors

javascript
import { S3Client, PutBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new PutBucketCorsCommand({
  Bucket: "my-bucket",
  CORSConfiguration: {
    CORSRules: [{
      AllowedOrigins: ["http://localhost:3000", "https://myapp.com"],
      AllowedMethods: ["GET", "HEAD", "PUT", "POST", "DELETE"],
      AllowedHeaders: ["*"],
      ExposeHeaders: ["ETag", "x-amz-meta-cid", "x-amz-request-id"],
      MaxAgeSeconds: 3600,
    }],
  },
}));

GetBucketCors

javascript
import { GetBucketCorsCommand } from "@aws-sdk/client-s3";

const { CORSRules } = await s3.send(new GetBucketCorsCommand({ Bucket: "my-bucket" }));
console.log(CORSRules);

DeleteBucketCors

javascript
import { DeleteBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteBucketCorsCommand({ Bucket: "my-bucket" }));

Riba ir numatytieji nustatymai

  • Iki 5 taisyklių vienam bucket (specifikacija leidžia 100; mes ribojame iki 5, kad naršyklės preflight atsakymas liktų kompaktiškas).
  • Bendra konfigūracija ribojama iki 64 KB serializuota.
  • Jei CORS konfigūracija nenustatyta, naršyklės preflight užklausos yra atmetamos — atitinka AWS S3 numatytąją poziciją. Sukonfigūruokite aiškias taisykles kilmėms, iš kurių iš tikrųjų aptarnaujate.

Praktinė saugumo pastaba

CORS yra naršyklės pusės patogumo sluoksnis, ne saugumo riba. Kiekvienam S3 API iškvietimui vis tiek reikalingas galiojantis SigV4 parašas, apskaičiuotas iš jūsų API rakto — leidžianti CORS konfigūracija neleidžia niekam naudoti jūsų bucket be šio kredencialo. Ką CORS iš tikrųjų apsaugo: nenumatytą kilmę (pvz., pasenusią jūsų programos kopiją dev.myapp.com), siunčiančią pasirašytas užklausas iš naršyklės konteksto.

Alternatyva prietaisų skydelyje

Failų puslapyje kiekvieno aplanko veiksmų meniu turi įrašą S3 CORS. Ta pati pagrindinė saugykla; jei nenorite rašyti PutBucketCors kodo, sukonfigūruokite ten.

Skirtumai nuo Amazon S3

SavybėAmazon S3IPFS Ninja S3
Saugojimo modelisKeičiami objektaiTuriniu adresuojami (nekintami CID)
Perrašymo elgsenaPakeičia objektą vietojeSukuria naują CID, senas CID vis dar pasiekiamas
VersijavimasPalaikomasNepalaikomas (naudokite CID versijavimui)
Serverio pusės šifravimasPalaikomasNepalaikomas (turinys yra IPFS tinkle)
Gyvavimo ciklo politikosPalaikomosNepalaikomos
Bucket politikos / ACLPalaikomosNaudokite gateway prieigos režimus
Presigned URLPalaikomiNaudokite pasirašytus įkėlimo tokenus
Maks. objekto dydis5 TB5 GB (multipart), 100 MB (single PUT)
RegionaiKeli regionaiTik us-east-1
ETag reikšmėMD5 maišaIPFS CID
Papildomos antraštėsStandartinės S3x-amz-meta-cid (IPFS CID)
CID formatasNetaikomaModernus CIDv1 (bafy…) naujiems įkėlimams; senesnis Qm… lieka galiojantis kaip įvestis
Bucket vardų erdvėGlobali (visame AWS)Globali (tarp visų IPFS Ninja paskyrų) — ta pati semantika
CORSPalaikomas PutBucketCorsPalaikomas PutBucketCors (5 taisyklių riba)

Migracija iš Amazon S3

Pakeiskite savo S3 kliento konfigūraciją:

diff
 const s3 = new S3Client({
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "AKIA...",
-    secretAccessKey: "wJalrX..."
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
+  forcePathStyle: true
 });

Jūsų esami PutObject, GetObject, ListObjectsV2 ir DeleteObject iškvietimai veikia be pakeitimų.

Migracija iš Filebase

Pakeiskite endpoint URL:

diff
 const s3 = new S3Client({
-  endpoint: "https://s3.filebase.com",
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "FILEBASE_KEY",
-    secretAccessKey: "FILEBASE_SECRET"
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
   forcePathStyle: true
 });