Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym samouczku pokazano, jak przekazywać pliki z przeglądarki bezpośrednio do usługi Azure Blob Storage bez uwidaczniania poświadczeń. Użyjesz języka TypeScript, aby zaimplementować wzorzec klucza valet z tokenami sygnatury dostępu współdzielonego (SAS) i tożsamością zarządzaną na potrzeby bezpiecznego uwierzytelniania bez klucza.
Przykładowa aplikacja obejmuje następujące elementy:
- Interfejs API Fastify, który generuje tokeny SAS z ograniczonym czasem dostępności
- Fronton React, który przekazuje pliki bezpośrednio do usługi Azure Storage
- Infrastruktura jako kod wdrożenia przy użyciu interfejsu wiersza polecenia dla deweloperów platformy Azure
Na koniec tego samouczka będziesz mieć działającą aplikację wdrożoną w usłudze Azure Container Apps, która demonstruje bezpieczne przesyłanie plików bez ujawniania w przeglądarce poświadczeń magazynu.
Warunki wstępne
Przed rozpoczęciem upewnij się, że masz:
- Subskrypcja platformy Azure — utwórz bezpłatnie subskrypcję platformy Azure
- Konto usługi GitHub do korzystania z usługi GitHub Codespaces (obejmuje bezpłatne miesięczne godziny)
Napiwek
W tym samouczku wykorzystujemy GitHub Codespaces, który zapewnia wstępnie skonfigurowane środowisko programistyczne w przeglądarce. Nie jest wymagana konfiguracja lokalna.
Architecture
Fronton żąda tokenu SAS z interfejsu API, a następnie przekazuje pliki bezpośrednio do usługi Azure Storage. Po przekazaniu interfejs API wyświetla listę wszystkich przekazanych plików z tokenami SAS, które są tylko do odczytu.
Najważniejsze pojęcia
Token delegowania użytkownika SAS
Aplikacja używa tokenów SAS z delegowaniem użytkownika do bezpiecznego uwierzytelniania bez użycia kluczy. Te tokeny są podpisane przy użyciu poświadczeń Microsoft Entra ID za pomocą zarządzanej tożsamości. Interfejs API generuje krótkotrwałe tokeny (10–60 minut) z określonymi uprawnieniami (odczyt, zapis lub usuwanie), co umożliwia przeglądarce przekazywanie plików bezpośrednio do magazynu bez ujawniania poświadczeń.
Wdrażanie interfejsu wiersza polecenia dla deweloperów platformy Azure
Wdróż pełną infrastrukturę za pomocą polecenia azd up. Tworzy aplikacje Azure Container Apps dla frontendu React i backendu API Fastify, konfiguruje zarządzane tożsamości i przypisuje uprawnienia w modelu RBAC. Infrastruktura używa szablonów Bicep zgodnie z zasadami platformy Azure Well-Architected Framework z modułami zweryfikowanymi platformy Azure, jeśli ma to zastosowanie.
Środowisko kontenera deweloperskiego
Kompletny przykładowy kod tego samouczka używa kontenera programistycznego w usłudze GitHub Codespaces lub lokalnym programie Visual Studio Code.
Uwaga / Notatka
Ten samouczek można również uruchomić lokalnie w programie Visual Studio Code za pomocą rozszerzenia Dev Containers. Kompletny przykładowy kod zawiera konfigurację kontenera deweloperskiego.
Otwórz przykład w usłudze GitHub Codespaces
Usługa GitHub Codespaces udostępnia środowisko programu VS Code oparte na przeglądarce ze wszystkimi wstępnie zainstalowanymi zależnościami.
Ważny
Wszystkie konta usługi GitHub mogą używać usługi Codespaces z bezpłatnymi godzinami każdego miesiąca. Aby uzyskać więcej informacji, zobacz GitHub Codespaces monthly included storage and core hours (Miesięczne miejsca do magazynowania i godzin rdzeni usługi GitHub Codespaces).
W przeglądarce internetowej otwórz przykładowe repozytorium i wybierz pozycję Code>Create codespace on main (Utwórz przestrzeń kodu na serwerze głównym).
Poczekaj na uruchomienie kontenera deweloperskiego. Ten proces uruchamiania może potrwać kilka minut. Pozostałe kroki opisane w tym samouczku mają miejsce w kontekście tego kontenera deweloperskiego.
Wdrażanie przykładu
Zaloguj się do Azure.
azd auth loginAprowizuj zasoby i wdróż przykład w środowisku hostingu.
azd upPo wyświetleniu monitu wprowadź następujące informacje:
Komunikat Wejść Wprowadź unikatową nazwę środowiska secure-uploadWybieranie subskrypcji platformy Azure do użycia Wybierz swoją subskrypcję z listy Wprowadź wartość parametru infrastruktury "location" Wybierz z dostępnych lokalizacji Alternatywnie, jeśli chcesz wyświetlić przygotowane zasoby, a następnie dane wyjściowe wdrożenia, możesz uruchomić następujące polecenie, aby wdrożyć bez monitów:
azd provisionNastępnie uruchom to polecenie, aby wdrożyć kod aplikacji:
azd deployJeśli zmienisz interfejs API lub kod aplikacji internetowej, możesz ponownie wdrożyć tylko kod aplikacji za pomocą jednego z następujących poleceń:
azd deploy app azd deploy apiPo zakończeniu wdrażania zanotuj adres URL wdrożonej aplikacji internetowej wyświetlany w terminalu.
(✓) Done: Deploying service app - Endpoint: https://app-gp2pofajnjhy6.calmtree-87e53015.eastus2.azurecontainerapps.io/Jest to przykładowy adres URL. Adres URL będzie inny.
Wypróbuj przykład
Otwórz wdrożona aplikację internetową na nowej karcie przeglądarki i wybierz plik PNG do przekazania. W folderze
./docs/mediajest dostępnych kilka plików PNG.Wybierz pozycję Pobierz token SAS, a następnie wybierz pozycję Przekaż plik.
Wyświetl przekazany plik w galerii poniżej przycisku przekazywania.
Co właśnie się stało?
- Plik przekazany bezpośrednio z przeglądarki do usługi Azure Storage przy użyciu ograniczonego czasowo tokenu SAS tylko do zapisu
- Obrazy z galerii ładują się bezpośrednio z Azure Storage za pomocą tokenów SAS z uprawnieniami tylko do odczytu.
- W przeglądarce nie ujawniono żadnych sekretów uwierzytelniających
Jak działa kod
Teraz, gdy aplikacja działa, sprawdź, jak kod implementuje bezpieczne przekazywanie plików. Aplikacja ma dwie główne części:
- Zaplecze interfejsu API — uwierzytelnia się za pomocą platformy Azure i generuje tokeny SAS
- Fronton React — przekazuje pliki bezpośrednio do usługi Azure Storage przy użyciu tokenów SAS
W poniższych sekcjach przedstawiono kluczowe implementacje kodu.
Serwer interfejsu API do generowania tokenów SAS i listowania plików
Serwer interfejsu API uwierzytelnia się w usłudze Azure Storage i generuje ograniczone czasowo tokeny SAS do użycia przez przeglądarkę.
Uwierzytelnianie przy użyciu tożsamości zarządzanej
Aplikacja używa kluczy delegowania użytkowników z tożsamością zarządzaną do uwierzytelniania, co jest najbezpieczniejszym podejściem dla aplikacji platformy Azure.
ChainedTokenCredential próbuje metod uwierzytelniania w następującej kolejności:
-
Na platformie Azure:
ManagedIdentityCredential(tożsamość usługi Container Apps) -
Rozwój lokalny:
AzureCliCredential(Twoja sesjaaz login)
// From: packages/api/src/lib/azure-storage.ts
export function getCredential(): ChainedTokenCredential {
if (!_credential) {
const clientId = process.env.AZURE_CLIENT_ID;
// Create credential chain with ManagedIdentity first
const credentials = [
new ManagedIdentityCredential(clientId ? { clientId } : undefined),
new AzureCliCredential()
];
_credential = new ChainedTokenCredential(...credentials);
}
return _credential;
}
Po uwierzytelnieniu utwórz element BlobServiceClient do interakcji z usługą Azure Storage:
// From: packages/api/src/lib/azure-storage.ts
export function getBlobServiceClient(accountName: string): BlobServiceClient {
const credential = getCredential();
const url = `https://${accountName}.blob.core.windows.net`;
return new BlobServiceClient(url, credential);
}
Generowanie tokenów SAS przy użyciu kluczy delegowania użytkownika
Tokeny SAS wymagają klucza delegowania użytkownika, który uwierzytelnia token za pomocą poświadczeń Microsoft Entra ID zamiast kluczy konta storage. Klucz jest prawidłowy dla określonego zakresu czasu:
const startsOn = new Date();
const expiresOn = new Date(startsOn.valueOf() + minutes * 60 * 1000);
const userDelegationKey = await blobServiceClient.getUserDelegationKey(
startsOn,
expiresOn
);
Generowanie tokenów SAS tylko do zapisu na potrzeby przekazywania plików
W przypadku przekazywania plików interfejs API generuje tokeny tylko do zapisu, które nie mogą odczytywać ani usuwać danych. Tokeny wygasają po 10 minutach:
// From: packages/api/src/routes/sas.ts
const DEFAULT_SAS_TOKEN_PERMISSION = 'w';
const DEFAULT_SAS_TOKEN_EXPIRATION_MINUTES = 10;
const sasToken = generateBlobSASQueryParameters(
{
containerName: container,
blobName: file,
permissions: BlobSASPermissions.parse(permission),
startsOn,
expiresOn
},
userDelegationKey,
accountName
).toString();
const sasUrl = `${blobClient.url}?${sasToken}`;
Dostępne poziomy uprawnień:
-
'r'- Odczyt (pobieranie/wyświetlanie) -
'w'- Zapisz (przesyłanie/nadpisywanie) — używane do przesyłania -
'd'-Usunąć -
'c'-Utworzyć -
'a'- Dodawanie (blobów dołączających)
Generowanie tokenów SAS tylko do odczytu na potrzeby listowania i wyświetlania plików
API generuje tokeny tylko do odczytu, które wygasają po 60 minutach, do wylistowania i wyświetlania plików.
// From: packages/api/src/routes/list.ts
const LIST_SAS_TOKEN_PERMISSION = 'r';
const LIST_SAS_TOKEN_EXPIRATION_MINUTES = 60;
const sasToken = generateBlobSASQueryParameters(
{
containerName: container,
blobName: blob.name,
permissions: BlobSASPermissions.parse(LIST_SAS_TOKEN_PERMISSION),
startsOn,
expiresOn
},
userDelegationKey,
accountName
).toString();
const sasUrl = `${blobClient.url}?${sasToken}`;
Klient aplikacji internetowej żąda i odbiera tokeny SAS z serwera API.
Fronton React żąda tokenów SAS z interfejsu API i używa ich do bezpośredniego przekazywania plików do usługi Azure Storage z przeglądarki.
Frontend przechodzi przez proces trzyetapowy:
- Żądanie tokenu SAS z interfejsu API dla określonego pliku
- Przekazywanie bezpośrednio do usługi Azure Storage przy użyciu adresu URL tokenu SAS
- Pobierz i wyświetl listę przekazanych plików z tokenami SAS tylko do odczytu
Ta architektura zapewnia uproszczone zaplecze — generuje tylko tokeny, nigdy nie obsługuje danych plików.
Żądanie tokenu SAS usługi Blob Storage z serwera interfejsu API
Gdy użytkownik wybierze plik i kliknie pozycję "Pobierz token SAS", fronton żąda tokenu SAS tylko do zapisu z interfejsu API:
// From: packages/app/src/App.tsx
const handleFileSasToken = () => {
const permission = 'w'; // write-only
const timerange = 10; // 10 minutes expiration
if (!selectedFile) return;
// Build API request URL
const url = `${API_URL}/api/sas?file=${encodeURIComponent(
selectedFile.name
)}&permission=${permission}&container=${containerName}&timerange=${timerange}`;
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => {
if (!response.ok) {
throw new Error(`Error: ${response.status} ${response.statusText}`);
}
return response.json();
})
.then((data: SasResponse) => {
const { url } = data;
setSasTokenUrl(url); // Store the SAS URL for upload
});
};
Co się stanie:
- Frontend wysyła:
GET /api/sas?file=photo.jpg&permission=w&container=upload&timerange=10 - Interfejs API zwraca:
{ url: "https://storageaccount.blob.core.windows.net/upload/photo.jpg?sv=2024-05-04&..." } - Ten adres URL jest ważny przez 10 minut i udziela dostępu tylko do zapisu do określonego bloba
Przekazywanie bezpośrednio do usługi Blob Storage przy użyciu tokenu SAS
Po odebraniu adresu URL tokenu SAS frontend konwertuje plik na ArrayBuffer i przesyła plik bezpośrednio do usługi Azure Storage — całkowicie pomijając interfejs API. Zmniejsza to obciążenie serwera i zwiększa wydajność.
Przekonwertuj plik na ArrayBuffer.
// From: packages/app/src/lib/convert-file-to-arraybuffer.ts
export function convertFileToArrayBuffer(file: File): Promise<ArrayBuffer | null> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const arrayBuffer = reader.result;
resolve(arrayBuffer as ArrayBuffer);
};
reader.onerror = () => {
reject(new Error('Error reading file.'));
};
reader.readAsArrayBuffer(file);
});
}
Następnie użyj elementu BlockBlobClient z @azure/storage-blob, aby załadować dane pliku przy użyciu adresu URL tokenu SAS.
// From: packages/app/src/App.tsx
const handleFileUpload = () => {
console.log('SAS Token URL:', sasTokenUrl);
// Convert file to ArrayBuffer
convertFileToArrayBuffer(selectedFile as File)
.then((fileArrayBuffer) => {
if (fileArrayBuffer === null || fileArrayBuffer.byteLength < 1) {
throw new Error('Failed to convert file to ArrayBuffer');
}
// Create Azure Storage client with SAS URL
const blockBlobClient = new BlockBlobClient(sasTokenUrl);
// Upload directly to Azure Storage
return blockBlobClient.uploadData(fileArrayBuffer);
})
.then((uploadResponse) => {
if (!uploadResponse) {
throw new Error('Upload failed - no response from Azure Storage');
}
setUploadStatus('Successfully finished upload');
// After upload, fetch the updated list of files
const listUrl = `${API_URL}/api/list?container=${containerName}`;
return fetch(listUrl);
});
};
Kluczowe punkty:
- Plik nigdy nie przechodzi przez serwer interfejsu API
- Przekazywanie odbywa się bezpośrednio z przeglądarki do usługi Azure Storage
- Token SAS uwierzytelnia żądanie
- Brak przepustowości serwera ani kosztów przetwarzania na potrzeby obsługi plików
Pobieranie pliku bezpośrednio z usługi Azure Storage i wyświetlanie obrazu miniatury
Po pomyślnym przesłaniu frontend pobiera listę wszystkich plików w kontenerze. Każdy plik na liście zawiera własny token SAS tylko do odczytu:
// From: packages/app/src/App.tsx
const listUrl = `${API_URL}/api/list?container=${containerName}`;
fetch(listUrl)
.then((response) => {
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
return response.json();
})
.then((data: ListResponse) => {
setList(data.list); // Array of SAS URLs with read permission
});
Przykład odpowiedzi:
{
"list": [
"https://storageaccount.blob.core.windows.net/upload/photo1.jpg?sv=2024-05-04&se=2025-12-18T15:30:00Z&sr=b&sp=r&...",
"https://storageaccount.blob.core.windows.net/upload/photo2.jpg?sv=2024-05-04&se=2025-12-18T15:30:00Z&sr=b&sp=r&..."
]
}
Frontend używa adresów SAS URL bezpośrednio w tagach obrazów. Przeglądarka pobiera obrazy z usługi Azure Storage przy użyciu osadzonych tokenów tylko do odczytu:
// From: packages/app/src/App.tsx
<Grid container spacing={2}>
{list.map((item) => {
const urlWithoutQuery = item.split('?')[0];
const filename = urlWithoutQuery.split('/').pop() || '';
const isImage = filename.endsWith('.jpg') ||
filename.endsWith('.png') ||
filename.endsWith('.jpeg');
return (
<Grid item xs={6} sm={4} md={3} key={item}>
<Card>
{isImage ? (
<CardMedia component="img" image={item} alt={filename} />
) : (
<Typography>{filename}</Typography>
)}
</Card>
</Grid>
);
})}
</Grid>
Jak to działa:
- Każdy adres URL na liście zawiera token SAS tylko do odczytu (
sp=r) - Przeglądarka wysyła żądania GET bezpośrednio do usługi Azure Storage
- Brak wymaganego uwierzytelniania — token znajduje się w adresie URL
- Tokeny wygasają po upływie 60 minut (skonfigurowanych w interfejsie API)
Czyszczenie zasobów
Po zakończeniu pracy z tym samouczkiem usuń wszystkie zasoby platformy Azure, aby uniknąć bieżących opłat:
azd down
Rozwiązywanie problemów
Zgłoś problemy z tym przykładem w repozytorium GitHub. Dołącz następujące elementy do problemu:
- Adres URL artykułu
- Krok lub kontekst w artykule, który był problematyczny
- Środowisko projektowe
Przykładowy kod
- Repozytorium GitHub: Azure-Samples/azure-typescript-upload-file-storage-blob
Dalsze kroki
Teraz, gdy wiesz już, jak bezpiecznie przekazywać pliki do usługi Azure Storage, zapoznaj się z następującymi tematami pokrewnymi:
- Dokumentacja usługi Azure Blob Storage — informacje na temat warstw magazynowania, zarządzania cyklem życia i zaawansowanych funkcji
- pakiet npm @azure/storage-blob — zapoznaj się z pełną dokumentacją zestawu SDK i dodatkowymi możliwościami
- Wzorzec Valet Key — zrozumienie wzorca architektury stojącego za tym rozwiązaniem
- Najlepsze rozwiązania dotyczące tożsamości zarządzanej — zabezpieczanie aplikacji platformy Azure