You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让前端安全直传大文件至Azure Blob Storage?规避Django中转超时

安全实现前端直传Azure Blob Storage的方案

当然有安全的方式,核心思路是让后端生成临时、受限权限的访问凭证,前端用这个凭证直接上传,完全绕开后端中转,既解决超时问题,又不会暴露存储账户的敏感信息。下面是两种主流方案及具体实现:

一、使用SAS令牌(最常用)

SAS(共享访问签名)是Azure提供的一种临时授权机制,后端可以生成仅允许特定操作(比如上传指定Blob)、短有效期的令牌,前端拿到后直接用它访问Blob存储。

1. Django后端生成SAS令牌

首先确保后端已安装azure-storage-blob库:

pip install azure-storage-blob

后端代码示例(结合Django身份验证,仅授权用户可获取令牌):

from azure.storage.blob import generate_blob_sas, BlobSasPermissions
from datetime import datetime, timedelta
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
import os

@login_required
def get_upload_sas(request):
    # 从环境变量读取存储信息,绝对不要硬编码密钥!
    storage_account = os.environ.get("AZURE_STORAGE_ACCOUNT")
    storage_key = os.environ.get("AZURE_STORAGE_KEY")
    container_name = "user-uploads"
    
    # 生成唯一Blob名称,避免重名(结合用户ID、时间戳和原文件名)
    filename = request.GET.get("filename")
    blob_name = f"user_{request.user.id}/{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}_{filename}"
    
    # 生成SAS令牌:仅允许创建/写入,有效期1小时,限制操作范围
    sas_token = generate_blob_sas(
        account_name=storage_account,
        container_name=container_name,
        blob_name=blob_name,
        account_key=storage_key,
        permission=BlobSasPermissions(create=True, write=True),
        expiry=datetime.utcnow() + timedelta(hours=1),
        # 可选:限制仅允许用户的IP上传(需根据实际场景配置)
        # ip_range="192.168.1.0-192.168.1.255"
    )
    
    upload_url = f"https://{storage_account}.blob.core.windows.net/{container_name}/{blob_name}?{sas_token}"
    return JsonResponse({"upload_url": upload_url, "blob_name": blob_name})

2. 前端用SAS令牌直传

拿到后端返回的upload_url后,直接用Fetch或Azure JS SDK上传,大文件建议分块上传避免超时:

基础Fetch上传:

async function uploadFile(file) {
    // 请求后端获取上传凭证
    const authRes = await fetch(`/get-upload-sas?filename=${encodeURIComponent(file.name)}`, {
        credentials: "include" // 携带Django会话Cookie,确保用户已登录
    });
    const { upload_url } = await authRes.json();

    // 上传文件到Blob存储
    const uploadRes = await fetch(upload_url, {
        method: "PUT",
        body: file,
        headers: { "Content-Type": file.type }
    });

    if (uploadRes.ok) {
        console.log("文件上传成功");
        // 可选:通知后端上传完成,记录Blob元数据/关联用户
        await fetch("/upload-finish", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ filename: file.name, blob_path: upload_url.split("?")[0] })
        });
    } else {
        console.error("上传失败", await uploadRes.text());
    }
}

大文件分块上传(用Azure JS SDK):

先安装SDK:

npm install @azure/storage-blob

代码示例:

import { BlockBlobClient } from "@azure/storage-blob";

async function uploadLargeFile(file, uploadUrl) {
    const blobClient = new BlockBlobClient(uploadUrl);
    // 分块上传:每块8MB,支持断点续传
    await blobClient.uploadBrowserData(file, {
        blockSize: 8 * 1024 * 1024, // 8MB每块
        concurrency: 3 // 并发上传3个块
    });
    console.log("大文件上传完成");
}

二、使用Azure AD OAuth2令牌(企业场景)

如果你的系统已经集成Azure AD身份验证,可以用OAuth2令牌授权前端上传:

  1. 后端引导用户完成Azure AD登录,获取针对Storage Blob Data Contributor权限的访问令牌
  2. 前端用这个令牌调用Azure Blob Storage的API上传文件
  3. 优势:无需管理SAS令牌,完全依赖Azure AD的身份体系,权限控制更精细

关键安全注意事项

  • 绝对不能暴露存储账户密钥:所有敏感信息必须存在后端环境变量或配置文件中,前端只能拿到临时凭证
  • 严格限制SAS权限:只给必要的权限(比如仅create/write,不要给read/delete),有效期设短(比如1小时内)
  • 后端前置验证:生成SAS前必须验证用户的上传权限(比如用户是否有权上传该类型文件、存储空间是否足够)
  • Blob命名规则:用用户ID、时间戳等生成唯一Blob名称,避免恶意覆盖或重名
  • 上传后校验:前端上传完成后,后端可以主动验证Blob是否存在、文件大小是否符合要求,确保上传完整性

内容的提问来源于stack exchange,提问作者user55665484375

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:05:58