IPFS üleslaadimise tokenid: turvalised uploadid
Uuri, kuidas allkirjastatud üleslaadimise tokenid võimaldavad turvaliselt IPFS-i failide üleslaadimist brauserist ja mobiilirakendusest ilma API võtit avaldamata.
Nacho founded IPFS.NINJA to make content-addressed storage feel as simple as an S3 PUT — a single API call, a permanent CID, no wallets or peer discovery to reason about.

- Genereeri allkirjastatud üleslaadimise tokenid serveripoolel, et brauserid ja mobiilirakendused ei näeks kunagi sinu toorest API võtit.
- Tokenitel on aegumise ajatempel ja kasutuspiirangud, mis vähendavad kahju, kui mõni token kunagi lekib.
- Otsesed kliendist-IPFS-i üleslaadimised tokenite kaudu kõrvaldavad serveri ribalaiuse kitsaskohad täielikult.
- Iga tokeni krüptograafilised allkirjad takistavad manipuleerimist või võltsitud üleslaadimise volituse loomist.
Kaasaegsete veebirakenduste ehitamine nõuab sageli failide üleslaadimist otse kasutajate brauseritest pilvsalvestusse. Siiski seisavad arendajad IPFS üleslaadimise turvalisuse osas silmitsi keerulise dilemmaga: kuidas lubada kliendipoolseid üleslaadimisi ilma oma väärtuslikke API võtmeid potentsiaalsele väärkasutusele paljastamata?
Enamik IPFS kinnitamisteenuseid sunnivad teid ebamugavale valikule: kas käsitleda kõiki üleslaadimisi serveripoolselt (luues pudelikaelu ja keerukust) või manustada oma API võti kliendikoodisse (turvanõukogu). IPFS.NINJA lahendab selle ainulaadse funktsiooniga, mida ükski teine kinnitamisteenus ei paku: allkirjastatud üleslaadimise tokenid.

Miks API võtmed pole brauserist üleslaadimiseks turvalised#
| Lähenemisviis | API võti kliendis? | Aegub automaatselt? | Täpsed piirangud? |
|---|---|---|---|
| API võtme manustamine | Jah (ebaturvaline) | Ei | Ei |
| Serveri vahendus | Ei | Ei rakendu | Ei rakendu |
| IPFS.NINJA üleslaadimise token | Ei | Jah | Jah |
Kliendipoolsete rakenduste ehitamisel, mis vajavad IPFS-i üleslaadimist, seisavad arendajad tavaliselt silmitsi mitme turvaprobleemiga:
API võtme paljastamise risk#
API võtmete otse brauseri JavaScripti manustamine tähendab, et igaüks saab teie lähtekoodi vaadata ja teie mandaadid välja tõmmata. See võib kaasa tuua:
- Volitamata üleslaadimised, mis tarbivad teie salvestusmahtu
- Teie kinnitamisteenuse konto potentsiaalne väärkasutus
- Turvanõuete rikkumised ettevõtte keskkondades
Serveripoolsed pudelikaelad#
Alternatiiv — kõigi üleslaadimiste suunamine läbi teie tagasüsteemi — tekitab mitmeid probleeme:
- Suurenenud serveri ribalaiuse kulud
- Kõrgem latentsus kasutajate jaoks
- Keerukamad infrastruktuuri nõuded
- Potentsiaalsed üksikud tõrkepunktid
Mobiilirakenduste turvalisus#
Mobiilirakendused seisavad silmitsi sarnaste väljakutsetega, kus rakenduspakettidesse salvestatud API võtmeid saab pöördprojekteerimise teel välja tõmmata.
IPFS üleslaadimise tokenite tutvustamine#
IPFS.NINJA allkirjastatud üleslaadimise tokenid pakuvad turvalist keskteed. Nii need töötavad:
- Server genereerib tokeni: teie tagasüsteem loob ajaliselt piiratud, allkirjastatud tokeni, kasutades teie API võtit
- Klient saab tokeni: token edastatakse turvaliselt teie esirakendusele
- Otsene üleslaadimine: kliendid laadivad otse IPFS.NINJA-sse, kasutades allkirjastatud tokenit
- Automaatne aegumine: tokenid aeguvad pärast määratud kestust, piirates paljastuse akent
See lähenemine ühendab serveripoolse autentimise turvalisuse kliendi otseüleslaadimise jõudluseeliste.
Üleslaadimise tokeni turvalisuse mõistmine#
Allkirjastatud üleslaadimise tokenid kasutavad krüptograafilisi allkirju autentsuse tagamiseks ilma teie peamist API võtit paljastamata. Iga token sisaldab:
- Aegumise ajatempel: automaatne kehtetuks muutumine pärast määratud kestust
- Kasutuspiirangud: valikulised piirangud failide arvule või kogumahtule
- Krüptograafiline allkiri: takistab rikkumist või võltsimist
- Väljaandja kontroll: seostub tagasi teie autenditud kontoga
Erinevalt API võtmetest on üleslaadimise tokenid loodud turvaliseks manustamiseks kliendipoolsesse koodi. Isegi kui need välja tõmmatakse, pakuvad need piiratud juurdepääsu, mis automaatselt aegub.
Tagasüsteemi teostus: Express.js näide#
Ehitame täieliku näite, mis näitab, kuidas teostada turvalisi kliendipoolseid IPFS üleslaadimisi. Esiteks, siin on Express.js tagasüsteem, mis genereerib üleslaadimise tokeneid:
// server.js
const express = require('express');
const cors = require('cors');
const app = express();
app.use(express.json());
app.use(cors());
// Your IPFS.NINJA API key (keep this secure on server-side only)
const IPFS_API_KEY = 'bws_1234567890abcdef1234567890abcdef12345678';
// Generate a signed upload token
app.post('/api/generate-upload-token', async (req, res) => {
try {
const response = await fetch('https://api.ipfs.ninja/upload-tokens', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': IPFS_API_KEY
},
body: JSON.stringify({
expiresIn: '1h', // Token valid for 1 hour
maxUploads: 10, // Optional: limit number of uploads
maxSizeMB: 50 // Optional: limit total upload size
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const tokenData = await response.json();
res.json({
success: true,
uploadToken: tokenData.token,
expiresAt: tokenData.expiresAt
});
} catch (error) {
console.error('Token generation failed:', error);
res.status(500).json({
success: false,
error: 'Failed to generate upload token'
});
}
});
// Optional: Endpoint to verify uploads completed successfully
app.post('/api/verify-upload', async (req, res) => {
const { cid } = req.body;
try {
const response = await fetch(`https://api.ipfs.ninja/pins/${cid}`, {
headers: {
'X-Api-Key': IPFS_API_KEY
}
});
const pinData = await response.json();
res.json({
success: true,
verified: pinData.pinned,
metadata: pinData
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Verification failed'
});
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});Esirakenduse teostus: turvaline kliendi üleslaadimine#
Nüüd, siin on esirakenduse kood, mis laadib faile turvaliselt üles, kasutades allkirjastatud tokenit:
<!DOCTYPE html>
<html>
<head>
<title>Secure IPFS Upload Demo</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
.upload-area { border: 2px dashed #ccc; padding: 20px; text-align: center; margin: 20px 0; }
.upload-area.dragover { border-color: #007cba; background: #f0f8ff; }
button { background: #007cba; color: white; border: none; padding: 10px 20px; cursor: pointer; }
.status { margin: 10px 0; padding: 10px; border-radius: 4px; }
.success { background: #d4edda; color: #155724; }
.error { background: #f8d7da; color: #721c24; }
.info { background: #d1ecf1; color: #0c5460; }
</style>
</head>
<body>
<h1>Secure IPFS Upload with Signed Tokens</h1>
<div class="upload-area" id="uploadArea">
<p>Drag & drop files here or click to select</p>
<input type="file" id="fileInput" multiple style="display: none;">
<button onclick="document.getElementById('fileInput').click()">Select Files</button>
</div>
<div id="status"></div>
<div id="results"></div>
<script>
class SecureIPFSUploader {
constructor() { this.uploadToken = null; this.tokenExpiry = null; this.setupEventListeners(); }
setupEventListeners() {
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('fileInput');
uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); uploadArea.classList.add('dragover'); });
uploadArea.addEventListener('dragleave', () => { uploadArea.classList.remove('dragover'); });
uploadArea.addEventListener('drop', (e) => { e.preventDefault(); uploadArea.classList.remove('dragover'); this.handleFiles(Array.from(e.dataTransfer.files)); });
fileInput.addEventListener('change', (e) => { this.handleFiles(Array.from(e.target.files)); });
}
async getUploadToken() {
if (this.uploadToken && this.tokenExpiry && new Date() < new Date(this.tokenExpiry)) return this.uploadToken;
try {
this.showStatus('Generating secure upload token...', 'info');
const response = await fetch('/api/generate-upload-token', { method: 'POST', headers: { 'Content-Type': 'application/json' } });
if (!response.ok) throw new Error(`Failed to generate token: ${response.statusText}`);
const data = await response.json();
if (!data.success) throw new Error(data.error || 'Token generation failed');
this.uploadToken = data.uploadToken; this.tokenExpiry = data.expiresAt;
return this.uploadToken;
} catch (error) { this.showStatus(`Token generation failed: ${error.message}`, 'error'); throw error; }
}
async uploadFile(file) {
try {
const token = await this.getUploadToken();
const fileBase64 = await this.fileToBase64(file);
this.showStatus(`Uploading ${file.name} to IPFS...`, 'info');
const response = await fetch('https://api.ipfs.ninja/upload/new', {
method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Signed ${token}` },
body: JSON.stringify({ content: fileBase64, description: `File uploaded via secure token: ${file.name}`, metadata: { filename: file.name, fileType: file.type, uploadedAt: new Date().toISOString(), uploadMethod: 'signed-token' } })
});
if (!response.ok) { const errorText = await response.text(); throw new Error(`Upload failed: ${response.status} ${errorText}`); }
const result = await response.json();
return { success: true, filename: file.name, cid: result.cid, size: result.sizeMB, ipfsUri: result.uris.ipfs, httpUrl: result.uris.url };
} catch (error) { return { success: false, filename: file.name, error: error.message }; }
}
async handleFiles(files) {
if (files.length === 0) return; this.clearResults();
try {
const results = await Promise.all(files.map(file => this.uploadFile(file)));
this.displayResults(results);
const successful = results.filter(r => r.success).length;
if (successful === results.length) this.showStatus(`✅ Successfully uploaded ${successful} file(s) to IPFS!`, 'success');
else this.showStatus(`⚠️ Uploaded ${successful}/${results.length} files. Check results below.`, 'error');
} catch (error) { this.showStatus(`Upload failed: ${error.message}`, 'error'); }
}
fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { resolve(reader.result.split(',')[1]); }; reader.onerror = error => reject(error); }); }
showStatus(message, type) { const s = document.getElementById('status'); s.className = `status ${type}`; s.textContent = message; }
displayResults(results) {
document.getElementById('results').innerHTML = '<h3>Upload Results:</h3>' + results.map(r => `<div class="status ${r.success ? 'success' : 'error'}" style="margin:10px 0;"><strong>${r.filename}</strong><br>${r.success ? `✅ CID: ${r.cid}<br>📊 Size: ${r.size} MB<br>🔗 URL: <a href="${r.httpUrl}" target="_blank">${r.httpUrl}</a>` : `❌ Error: ${r.error}`}</div>`).join('');
}
clearResults() { document.getElementById('results').innerHTML = ''; }
}
const uploader = new SecureIPFSUploader();
</script>
</body>
</html>Täiendavad turvakaalutlused#
IPFS üleslaadimise turvalisuse teostamisel allkirjastatud tokenitega kaaluge neid lisameetmeid:
Tokeni ulatuse piirangud#
Seadistage tokenid asjakohaste piirangutega:
// Generate token with specific constraints
const restrictedToken = await fetch('https://api.ipfs.ninja/upload-tokens', {
method: 'POST',
headers: { 'X-Api-Key': IPFS_API_KEY },
body: JSON.stringify({
expiresIn: '30m', maxUploads: 5, maxSizeMB: 10,
allowedMimeTypes: ['image/jpeg', 'image/png'],
ipWhitelist: ['192.168.1.0/24']
})
});Sisu valideerimine#
Valideerige alati üleslaaditud sisu oma tagasüsteemis:
app.post('/api/validate-upload', async (req, res) => {
const { cid } = req.body;
try {
const response = await fetch(`https://ipfs.ninja/ipfs/${cid}`);
const contentType = response.headers.get('content-type');
if (!isValidContentType(contentType)) {
await deleteFromIPFS(cid);
return res.status(400).json({ error: 'Invalid content type' });
}
res.json({ success: true, validated: true });
} catch (error) { res.status(500).json({ error: 'Validation failed' }); }
});Kiirusepiirang#
Rakendage oma tokeni genereerimise lõpp-punktile täiendav kiirusepiirang:
const rateLimit = require('express-rate-limit');
const tokenLimiter = rateLimit({
windowMs: 15 * 60 * 1000, max: 10,
message: 'Too many token requests, please try again later'
});
app.use('/api/generate-upload-token', tokenLimiter);Eelised traditsiooniliste lähenemisviiside ees#
Allkirjastatud üleslaadimise tokenid pakuvad mitmeid eeliseid alternatiivsete IPFS üleslaadimise turvameetodite ees:
vs. serveripoolne proksimine#
- Jõudlus: otseüleslaadimised kõrvaldavad serveri ribalaiuse kasutamise
- Skaleeritavus: serveripoolsed pudelikaelad puuduvad kõrge üleslaadimise perioodidel
- Kulu: vähenenud ribalaiuse ja töötlemise kulud
- Kasutajakogemus: parem üleslaadimiskiirus ja edenemise jälgimine
vs. kliendipoolne API võti#
- Turvalisus: API võtme väljavõtmise või väärkasutuse risk puudub
- Vastavus: vastab turvaauditi nõuetele
- Juurdepääsukontroll: peeneteralisne õiguste haldus ja automaatne aegumine
- Jälgimine: parem üleslaadimisallikate ja -mustrite jälgimine
vs. teised kinnitamisteenused#
IPFS.NINJA on praegu ainus suurem kinnitamisteenus, mis pakub allkirjastatud üleslaadimise tokeneid. Konkurendid nagu Pinata nõuavad kas serveripoolset proksimist või kliendipoolse API võtme paljastamist, muutes selle ainulaadseks eristajaks.
Lisateabe saamiseks IPFS.NINJA võrdluse kohta teiste teenustega vaadake meie põhjalikku võrdlusjuhendit.
Tootmisse juurutamise näpunäited#
Allkirjastatud üleslaadimise tokenite tootmisse juurutamisel:
Keskkonna seadistamine#
const config = {
ipfsApiKey: process.env.IPFS_API_KEY,
tokenExpiry: process.env.UPLOAD_TOKEN_EXPIRY || '1h',
maxFileSize: process.env.MAX_FILE_SIZE_MB || 50,
allowedOrigins: process.env.ALLOWED_ORIGINS?.split(',') || ['localhost:3000']
};Jälgimine ja logimine#
const winston = require('winston');
const logger = winston.createLogger({
level: 'info', format: winston.format.json(),
transports: [new winston.transports.File({ filename: 'upload-security.log' })]
});
logger.info('Upload token generated', {
userId: req.user.id, clientIP: req.ip, userAgent: req.get('User-Agent'), expiresAt: tokenData.expiresAt
});Vigade käsitlemine#
app.use((error, req, res, next) => {
logger.error('Upload token error', { error: error.message, stack: error.stack, userId: req.user?.id, endpoint: req.path });
res.status(500).json({ success: false, error: 'An internal error occurred. Please try again.' });
});Integratsioon populaarsete raamistikega#
React Hook#
import { useState, useCallback } from 'react';
export function useSecureIPFSUpload() {
const [uploading, setUploading] = useState(false);
const [uploadToken, setUploadToken] = useState(null);
const getToken = useCallback(async () => {
if (uploadToken?.expiresAt && new Date() < new Date(uploadToken.expiresAt)) return uploadToken.token;
const response = await fetch('/api/generate-upload-token', { method: 'POST' });
const data = await response.json(); setUploadToken(data); return data.uploadToken;
}, [uploadToken]);
const uploadFile = useCallback(async (file) => {
setUploading(true);
try { const token = await getToken(); /* Upload logic here... */ } finally { setUploading(false); }
}, [getToken]);
return { uploadFile, uploading };
}Vue.js Composable#
import { ref } from 'vue';
export function useSecureUpload() {
const uploading = ref(false); const uploadProgress = ref(0);
const uploadFile = async (file) => { uploading.value = true; /* Implementation here... */ };
return { uploading: readonly(uploading), uploadProgress: readonly(uploadProgress), uploadFile };
}Korduma kippuvad küsimused#
Mis on IPFS üleslaadimise tokenid ja kuidas need erinevad API võtmetest?#
IPFS üleslaadimise tokenid on lühiajalised, krüptograafiliselt allkirjastatud volitused, mille genereerib sinu server sinu API võtit kasutades. Erinevalt API võtmetest, mis annavad täieliku juurdepääsu kontole, on üleslaadimise tokenitel sisseehitatud aegumisaeg, valikulised failiarvude ja -suuruse piirangud ning need on loodud kliendipoolses koodis turvaliseks kasutamiseks.
Kas ma saan piirata, mida üleslaadimise token teha saab?#
Jah. Tokeni genereerimisel saad määrata expiresIn (nt 1h), maxUploads (nt 10 faili), maxSizeMB (nt 50 MB), allowedMimeTypes (nt ['image/jpeg']) ja ipWhitelist (nt CIDR-vahemikud). Isegi kui token ekstraheeritakse kliendipoolsest koodist, saab ründaja üles laadida ainult nende piirangute raames enne tokeni aegumist.
Kuidas genereerida üleslaadimise tokenit Node.js-is / Expressis?#
Saada POST-päring aadressile https://api.ipfs.ninja/upload-tokens koos oma API võtmega X-Api-Key päises ja JSON-kehaga, mis sisaldab expiresIn, maxUploads ja maxSizeMB. Vastus sisaldab allkirjastatud tokeni stringi ja expiresAt ajatemplit. Edasta see token oma frontendile; klient saadab selle seejärel üleslaadimise lõpp-punkti kutsudes kui Authorization: Signed <token>.
Kas IPFS.NINJA on ainus pinning-teenus, mis toetab allkirjastatud üleslaadimise tokeneid?#
Jah, alates 2026. aastast on IPFS.NINJA ainus suur IPFS pinning-teenus, mis pakub allkirjastatud, piiratud üleslaadimise tokeneid. Teised teenused nõuavad kas kõigi üleslaadimiste suunamist läbi sinu backend’i või täieliku API võtme manustamist kliendikoodis.
Mis juhtub, kui üleslaadimise token varastatakse või lekib?#
Kokkupuudet piiravad tokeni sisseehitatud piirangud: see aegub automaatselt pärast konfigureeritud kestust, seda saab kasutada ainult piiratud arvu üleslaadimiste jaoks, see ei saa ületada konfigureeritud suurusepiirangut ja seda ei saa kasutada kinnitatud failide loetlemiseks, kustutamiseks ega haldamiseks — need toimingud nõuavad endiselt sinu peamist API võtit.
Kokkuvõte#
Allkirjastatud üleslaadimise tokenid lahendavad kriitilise turvaprobleemi detsentraliseeritud rakenduste arendamisel. Pakkudes turvalist viisi kliendipoolsete otseüleslaadimiste lubamiseks IPFS-i ilma API võtmete paljastamiseta, avavad need uusi arhitektuurseid võimalusi kaasaegsetele veebirakendustele.
Olenemata sellest, kas ehitate sisuhaldussüsteemi, NFT turgu või mis tahes rakendust, mis nõuab turvalisi failide üleslaadimisi, pakuvad IPFS.NINJA üleslaadimise tokenid teile vajalikku turvalisust ja paindlikkust. Teostus on lihtne, turvaeelised on märkimisväärsed ja jõudluse parandused on olulised.
IPFS põhitõdede kohta lisateabe saamiseks vaadake meie juhendit mis on IPFS kinnitamine või uurige meie täielikku API õpetust. Erinevaid valikuid hindavate arendajate jaoks pakub meie parimate IPFS kinnitamisteenuste võrdlus põhjalikke ülevaateid.
Valmis kinnitamist alustama? Looge tasuta konto --- 500 faili, 1 GB salvestusruum, spetsiaalne gateway. Krediitkaarti pole vaja.
Selle artikli kohta
See artikkel loodi tehisintellekti abiga, inimese poolt üle vaadatud ja enne avaldamist kontrollitud IPFS.NINJA platvormil. Loe, kuidas me tehisintellekti oma sisus kasutame .

Autorist
Nacho Coll
Founder & Engineer at IPFS.NINJA
Nacho founded IPFS.NINJA to make content-addressed storage feel as simple as an S3 PUT — a single API call, a permanent CID, no wallets or peer discovery to reason about. Writes about IPFS internals, decentralized storage patterns, and the pinning-service landscape from the operator side of the wire.
