You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Azure与Google Drive对接的可行性及基于ASP.NET Core的Azure部署系统免费文件存储实现方案

当然可以!Azure部署的ASP.NET Core系统完全能对接Google Drive存储用户文件

我刚好做过类似的需求,用来节省Azure Blob存储的成本,这个方案是完全可行的——Google提供了官方的Drive API,能让你的ASP.NET Core应用直接和Google Drive进行文件交互,不管是部署在Azure还是其他平台都能正常工作。下面我分两种常见场景给你讲具体实现步骤:


场景1:将文件存储到应用专属的Google Drive空间(无需用户授权)

这种情况适合所有用户上传的文件都存在你自己管理的Google Drive文件夹里,不需要用户登录Google账号,用服务账号来实现:

1. 前期在Google Cloud Console的准备

  • 登录Google Cloud Console,新建一个项目,搜索并启用「Google Drive API」。
  • 创建一个服务账号:在「IAM与管理员」→「服务账号」页面点击「创建服务账号」,填写信息后,点击「创建并继续」,权限可以暂时选「项目→编辑者」(后续可以缩小权限),完成创建。
  • 给服务账号生成密钥:进入刚创建的服务账号详情页,切换到「密钥」标签,点击「添加密钥」→「创建新密钥」,选择JSON格式,下载密钥文件(务必妥善保管,不要提交到代码仓库)。
  • 共享Drive文件夹给服务账号:在你的Google Drive里新建一个文件夹,右键→「共享」,输入服务账号的邮箱(就是密钥文件里的client_email字段值),给它「编辑」权限,保存。记住这个文件夹的ID(浏览器地址栏里folders/后面的字符串)。

2. 在ASP.NET Core项目中集成

  • 安装必要的NuGet包:
    Install-Package Google.Apis.Drive.v3
    Install-Package Google.Apis.Auth
    
  • 编写一个Google Drive存储服务类,封装上传/下载逻辑:
    using Google.Apis.Drive.v3;
    using Google.Apis.Auth.OAuth2;
    using System.IO;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    
    public class GoogleDriveStorageService
    {
        private readonly DriveService _driveService;
        private readonly string _rootFolderId;
    
        public GoogleDriveStorageService(string serviceAccountJson, string rootFolderId)
        {
            // 从JSON密钥初始化凭据,只请求必要的Drive文件权限
            var credential = GoogleCredential.FromJson(serviceAccountJson)
                .CreateScoped(DriveService.Scope.DriveFile);
    
            _driveService = new DriveService(new()
            {
                HttpClientInitializer = credential,
                ApplicationName = "你的ASP.NET Core应用名称"
            });
    
            _rootFolderId = rootFolderId;
        }
    
        // 上传文件到指定文件夹
        public async Task<string> UploadUserFileAsync(Stream fileStream, string fileName, string contentType)
        {
            var fileMetadata = new Google.Apis.Drive.v3.Data.File()
            {
                Name = fileName,
                Parents = new List<string> { _rootFolderId }
            };
    
            // 创建上传请求,只返回文件ID
            var uploadRequest = _driveService.Files.Create(fileMetadata, fileStream, contentType);
            uploadRequest.Fields = "id";
    
            var uploadResponse = await uploadRequest.UploadAsync();
            if (uploadResponse.Status != Google.Apis.Upload.UploadStatus.Completed)
            {
                throw uploadResponse.Exception;
            }
    
            // 返回上传后的文件ID,用于后续下载或删除
            return uploadRequest.ResponseBody.Id;
        }
    
        // 可选:添加下载、删除文件的方法
        public async Task<Stream> DownloadFileAsync(string fileId)
        {
            var stream = new MemoryStream();
            var downloadRequest = _driveService.Files.Get(fileId);
            await downloadRequest.DownloadAsync(stream);
            stream.Position = 0;
            return stream;
        }
    }
    
  • 在Program.cs中注册服务,从配置读取密钥和文件夹ID:
    var builder = WebApplication.CreateBuilder(args);
    
    // 从配置获取参数(建议用Azure应用设置,不要硬编码)
    var serviceAccountJson = builder.Configuration["GoogleDrive:ServiceAccountJson"];
    var rootFolderId = builder.Configuration["GoogleDrive:RootFolderId"];
    
    builder.Services.AddSingleton<GoogleDriveStorageService>(_ => 
        new GoogleDriveStorageService(serviceAccountJson, rootFolderId));
    
    // ... 其他中间件配置
    

3. Azure部署的注意事项

  • 不要把密钥文件打包到部署包,而是把JSON内容粘贴到Azure App Service的应用设置里(配置→应用设置→新建应用设置,键为GoogleDrive:ServiceAccountJson,值为JSON的内容),文件夹ID同理。
  • 确保Azure App Service的出站网络能访问Google API(默认是允许的,如果你的App Service在虚拟网络中,需要配置出站规则放行)。
  • 大文件上传需要用分块上传逻辑,上面的示例适合100MB以内的文件,超过的话要调用CreateMediaUpload并设置分块大小。

场景2:让用户将文件存储到自己的Google Drive(需要用户授权)

如果想让用户上传的文件存在他们自己的Google Drive里,需要用OAuth 2.0让用户授权你的应用访问他们的Drive:

1. Google Cloud Console配置

  • 同样启用Google Drive API,然后创建「OAuth 2.0客户端ID」,类型选「Web应用」,填写授权回调URL(比如你的Azure App Service地址 + /signin-google)。
  • 记住生成的Client ID和Client Secret。

2. ASP.NET Core集成OAuth

  • 安装NuGet包:
    Install-Package Google.Apis.Auth.AspNetCore3
    
  • 在Program.cs中配置Google OAuth登录:
    builder.Services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddGoogle(options =>
    {
        options.ClientId = builder.Configuration["GoogleAuth:ClientId"];
        options.ClientSecret = builder.Configuration["GoogleAuth:ClientSecret"];
        // 请求Drive文件操作的权限
        options.Scope.Add(DriveService.Scope.DriveFile);
        // 保存用户的凭据到Cookie,方便后续调用API
        options.SaveTokens = true;
    });
    
  • 在控制器中获取用户的凭据并创建DriveService:
    [Authorize]
    public class UserDriveController : Controller
    {
        private readonly IConfiguration _configuration;
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public UserDriveController(IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
        {
            _configuration = configuration;
            _httpContextAccessor = httpContextAccessor;
        }
    
        public async Task<IActionResult> UploadUserFile(IFormFile file)
        {
            // 从HttpContext获取用户的Google访问令牌
            var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
            var credential = new UserCredential(new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new ClientSecrets
                {
                    ClientId = _configuration["GoogleAuth:ClientId"],
                    ClientSecret = _configuration["GoogleAuth:ClientSecret"]
                }
            }), "user", new TokenResponse { AccessToken = accessToken });
    
            var driveService = new DriveService(new()
            {
                HttpClientInitializer = credential,
                ApplicationName = "你的应用名称"
            });
    
            // 接下来的上传逻辑和场景1类似,只是文件会存在用户自己的Drive里
            var fileMetadata = new Google.Apis.Drive.v3.Data.File()
            {
                Name = file.FileName
            };
    
            using var stream = file.OpenReadStream();
            var uploadRequest = driveService.Files.Create(fileMetadata, stream, file.ContentType);
            await uploadRequest.UploadAsync();
    
            return Ok(new { FileId = uploadRequest.ResponseBody.Id });
        }
    }
    

总结

两种方案都能满足你的需求:

  • 如果是系统统一存储用户文件,选场景1(服务账号),无需用户操作,管理更方便;
  • 如果要让用户自己管理上传的文件,选场景2(OAuth授权),更符合用户的数据归属需求。

部署到Azure后,只要配置好凭据,就能正常运行,完全可以替代Azure存储来保存用户上传的文件,节省成本。

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

火山引擎 最新活动