ASP.NET MVC调用Google Drive API出现重定向URI不匹配和异常如何解决?
问题原因
redirect_uri_mismatch错误核心原因:你使用的GoogleWebAuthorizationBroker是面向桌面/本机应用设计的授权类,它会自动在本地启动一个随机端口的HTTP服务来接收授权回调,因此生成的重定向地址是http://127.0.0.1:随机端口/authorize/,端口每次运行都会变化,你无法提前把所有可能的端口地址都添加到Google Cloud控制台的重定向URI列表中,自然会触发匹配失败。- 空
TokenResponseException异常确实是由redirect_uri_mismatch导致:授权流程因为地址不匹配中断,Google没有返回任何token相关的响应,SDK就会抛出这个无内容的token异常,最终service变量初始化失败返回null。
解决方法
根据你的业务需求选择对应方案即可:
场景1:需要让访问网站的用户授权访问他们自己的Google Drive
- 进入Google Cloud控制台,将你当前使用的OAuth客户端类型修改为「Web应用」,删除之前的桌面端配置。
- 在重定向URI列表中添加你项目的固定回调地址,比如本地测试用
http://localhost:61506/AutoFileTransfer/Callback,上线后替换为生产域名对应的回调地址。 - 移除原代码中
GoogleWebAuthorizationBroker相关逻辑,使用适配ASP.NET的OAuth授权流程:
// 简化的Web端授权初始化示例 using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2.Flows; public static string[] Scopes = { DriveService.Scope.Drive }; public static GoogleAuthorizationCodeFlow GetAuthFlow() { var CSPath = System.Web.Hosting.HostingEnvironment.MapPath("~/"); using var stream = new FileStream(Path.Combine(CSPath, "client_secret.json"), FileMode.Open, FileAccess.Read); return new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = GoogleClientSecrets.Load(stream).Secrets, Scopes = Scopes, DataStore = new FileDataStore(Path.Combine(CSPath, "DriveServiceCredentials.json"), true) }); } // 授权跳转逻辑写在控制器方法中 public ActionResult Auth() { var flow = GetAuthFlow(); // 回调地址要和控制台配置完全一致 var authUri = flow.CreateAuthorizationCodeRequest("http://localhost:61506/AutoFileTransfer/Callback").Build(); return Redirect(authUri.ToString()); } // 回调接收逻辑 public async Task<ActionResult> Callback(string code) { var flow = GetAuthFlow(); var token = await flow.ExchangeCodeForTokenAsync("user", code, "http://localhost:61506/AutoFileTransfer/Callback", CancellationToken.None); // 用token初始化DriveService var service = new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = await flow.LoadTokenAsync("user", CancellationToken.None), ApplicationName = "GoogleDriveMVCUpload", }); // 后续业务逻辑 }
场景2:服务端固定上传到你自己的Google Drive,不需要用户授权
推荐直接使用服务账号方案,完全不需要走用户授权流程,不会出现重定向问题:
- 在Google Cloud控制台创建服务账号,下载JSON格式的密钥文件放到项目中。
- 进入你的Google Drive,找到要上传的目标文件夹,共享给服务账号的邮箱地址,授予「编辑」权限。
- 替换服务初始化代码:
public static DriveService GetService() { var keyPath = System.Web.Hosting.HostingEnvironment.MapPath("~/service-account-key.json"); GoogleCredential credential; using (var stream = new FileStream(keyPath, FileMode.Open, FileAccess.Read)) { credential = GoogleCredential.FromStream(stream) .CreateScoped(DriveService.Scope.Drive); } return new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "GoogleDriveMVCUpload", }); }
内容的提问来源于stack exchange,提问作者William Tjandra
相关产品推荐
相关产品推荐

