google 驱动器 Api 未在生产中工作 "Failed to launch browser with"

google drive Api not working in production "Failed to launch browser with"

我遇到 google 驱动器 API 的问题,它在我的本地机器上工作,但是一旦我将项目部署到服务器,google 驱动器 API 服务停止工作,
它抛出一个 oauth2 异常,我想我需要在 google 驱动器 api 控制台上做一些事情,但我不知道它是什么或从哪里开始
我当前使用的凭据是 OAuth 2.0 客户端 ID 和客户端密码,类型为 Desktop。

如有任何帮助,我们将不胜感激

这是我得到的例外情况。

  An unhandled exception occurred while processing the request.

AggregateException: One or more errors occurred. (Failed to launch browser with "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=813040219774-atf2l4751d1tkjeegoeb7d4lituel9ev.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A42257%2Fauthorize%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" for authorization. See inner exception for details.)
System.Threading.Tasks.Task<TResult>.GetResultCore(bool waitCompletionNotification)

NotSupportedException: Failed to launch browser with "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=813040219774-atf2l4751d1tkjeegoeb7d4lituel9ev.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A42257%2Fauthorize%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" for authorization. See inner exception for details.
Google.Apis.Auth.OAuth2.LocalServerCodeReceiver.ReceiveCodeAsync(AuthorizationCodeRequestUrl url, CancellationToken taskCancellationToken)

Stack Query Cookies Headers Routing
AggregateException: One or more errors occurred. (Failed to launch browser with "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=813040219774-atf2l4751d1tkjeegoeb7d4lituel9ev.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A42257%2Fauthorize%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" for authorization. See inner exception for details.)
System.Threading.Tasks.Task<TResult>.GetResultCore(bool waitCompletionNotification)
ElseForty.FileServices.Files+GoogleDrive.GetService() in Files.cs
ElseForty.FileServices.Files+GoogleDrive.UploadFileAsync(IFormFile file) in Files.cs
ElseForty.Controllers.BugReportController.Send(User_BugReportViewModel model) in BugReportController.cs
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask<IActionResult> actionResultValueTask)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Show raw exception details
NotSupportedException: Failed to launch browser with "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=813040219774-atf2l4751d1tkjeegoeb7d4lituel9ev.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A42257%2Fauthorize%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" for authorization. See inner exception for details.
Google.Apis.Auth.OAuth2.LocalServerCodeReceiver.ReceiveCodeAsync(AuthorizationCodeRequestUrl url, CancellationToken taskCancellationToken)
Google.Apis.Auth.OAuth2.AuthorizationCodeInstalledApp.AuthorizeAsync(string userId, CancellationToken taskCancellationToken)
Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(Initializer initializer, IEnumerable<string> scopes, string user, CancellationToken taskCancellationToken, IDataStore dataStore, ICodeReceiver codeReceiver)
Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(ClientSecrets clientSecrets, IEnumerable<string> scopes, string user, CancellationToken taskCancellationToken, IDataStore dataStore, ICodeReceiver codeReceiver)

Show raw exception details

更新

我正在为我的 Web 应用程序使用 google 驱动器 api 供访问者上传图片,

          public static DriveService GetService()
        {
            UserCredential credential;

            using (var stream =
              new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
            {
                string credPath = "token.json";
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;
                Console.WriteLine("Credential file saved to: " + credPath);
            }

            return new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "elsefortydisk",
            });
        }

        public static async Task<string> UploadFileAsync(IFormFile file)
        {
            var fileName = GetUniqueFileName(file.FileName);
            var service = GetService();
            var fileMetadata = new Google.Apis.Drive.v3.Data.File();
            fileMetadata.Name = Path.GetFileName(fileName);
            fileMetadata.MimeType = file.ContentType;
            fileMetadata.Parents = new List<string>() { "14kECd48VL6xhS9ArQL3Lh7oLT6npAVg-" };

            FilesResource.CreateMediaUpload request;
            using (var stream = file.OpenReadStream())
            {
                request = service.Files.Create(fileMetadata, stream, file.ContentType);

                request.Fields = "id";
                await request.UploadAsync();
            }
            var responce = request.ResponseBody;
            var pemission = new Permission();
            pemission.Type = "anyone";
            pemission.Role = "reader";
            try
            {
                service.Permissions.Create(pemission, responce.Id).Execute();  
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: " + e.Message);
            }

            return responce.Id;
        }

问题您将问题标记为 asp.net 核心,并且声明您正在将其上传到服务器。然而,您还声明您已经在 google 开发人员控制台

上创建了一个桌面客户端

am currently using are OAuth 2.0 Client IDs and client Secret, type Desktop.

如果您正在使用 asp .net 核心,那么您正在创建一个 Web 应用程序,并且应该已经创建了 Web 浏览器凭据。

您正在使用的代码是针对已安装/桌面应用程序设计的,其中代码在用户正在使用的计算机上 运行。示例 您正在使用 GoogleWebAuthorizationBroker.AuthorizeAsync,它旨在与已安装的应用程序一起使用。它的设计方式会在 运行 所在的机器上打开浏览器 window,这就是您看到以下错误消息的原因。

NotSupportedException: Failed to launch browser with "https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&client_id=813040219774-atf2l4751d1tkjeegoeb7d4lituel9ev.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A42257%2Fauthorize%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" for authorization. See inner exception for details.

您的代码可以在本地运行,因为它能够在其 运行 机器上打开浏览器 window,而在网络服务器上 运行 它将尝试打开网络浏览器在 Web 服务器上同意 window 这不是您希望它做的您希望它在用户客户端计算机上打开浏览器同意。

如果您尝试使用 Asp .net core 创建 Web 应用程序,那么您需要创建 Web 应用程序凭据,并按如下方式配置 Web 应用程序。

配置 asp.net 核心应用程序以访问 google apis 是完全不同的,我在这里有一个教程,它将引导您完成设置的配置,但是 Asp .net core 3 and Google login

// This configures Google.Apis.Auth.AspNetCore3 for use in this app.
 services
     .AddAuthentication(o =>
     {
         // This forces challenge results to be handled by Google OpenID Handler, so there's no
         // need to add an AccountController that emits challenges for Login.
         o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
         // This forces forbid results to be handled by Google OpenID Handler, which checks if
         // extra scopes are required and does automatic incremental auth.
         o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
         // Default scheme that will handle everything else.
         // Once a user is authenticated, the OAuth2 token info is stored in cookies.
         o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
       })
       .AddCookie()
       .AddGoogleOpenIdConnect(options =>
       {
          options.ClientId = ClientId;
          options.ClientSecret = ClientSecret;
           });

调用请求授权的api本身主要是通过一个属性完成的。

[GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)]
public async Task<IActionResult> DriveFileList([FromServices] IGoogleAuthProvider auth)
{
    GoogleCredential cred = await auth.GetCredentialAsync();
    var service = new DriveService(new BaseClientService.Initializer
    {
        HttpClientInitializer = cred
    });
    var files = await service.Files.List().ExecuteAsync();
    var fileNames = files.Files.Select(x => x.Name).ToList();
    return View(fileNames);
}

提示

桌面/已安装的应用程序旨在 运行 在用户面前使用的单台计算机上。

Web 应用程序 运行 来自 Web 服务器,用户通过 Web 浏览器与它们联系。

这是两种不同类型的应用程序,在 google 开发人员控制台上创建的客户端不同,使用这些客户端的代码也不同。