Возникли проблемы при аутентификации пользователя с помощью YouTubeAPI OAuth2 из функции Azure? - PullRequest
0 голосов
/ 31 марта 2020

У меня есть функция Azure, в которой есть код для загрузки видео на мой канал YouTube, когда в контейнере "video" есть видеофайл. Код, который я использую, взят из примера кода YouTube API: https://developers.google.com/youtube/v3/docs/videos/insert. Я взял этот код и поместил его в функцию Azure (код ниже). Когда я компилирую и запускаю функцию локально, она работает нормально, и я могу загрузить видео с помощью Azure Storage Explorer (ниже - журнал вывода консоли), и я вижу, что видео отлично загружаются на моем канале YouTube.

Однако, когда я публикую sh функцию на портале Azure и запускаю функцию, функция просто TimeOuts, потому что она ожидает пользовательский интерфейс, так как для входа требуется взаимодействие с пользователем. Мне интересно, как я могу преодолеть эту проблему OAuth? Есть ли способ добавить шаг рабочего процесса в приложение Azure, которое запрашивает учетные данные у пользователя? Я хотел бы иметь возможность использовать мою функцию на Azure без тайм-аута.

Ошибка при публикации функции sh на Azure: enter image description here

Вывод на консоль при локальном запуске:

Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.
[3/26/2020 4:46:17 AM] Host lock lease acquired by instance ID '000000000000000000000000A74A8599'.
[3/26/2020 4:48:27 AM] Executing 'Function1' (Reason='New blob detected: video/Test.mp4', Id=62898b7f-878f-48b2-ace1-dee34a884652)
[3/26/2020 4:48:46 AM] test.mp4
[3/26/2020 4:48:46 AM] Getting client secrets.
[3/26/2020 4:48:46 AM] Done getting secrets.
[3/26/2020 4:48:46 AM] Creating youtube service
[3/26/2020 4:48:46 AM] Done creating service.
[3/26/2020 4:48:46 AM] Trying to upload video
[3/26/2020 4:49:21 AM] Done uploading video.
[3/26/2020 4:49:21 AM] Executed 'Function1' (Succeeded, Id=62898b7f-878f-48b2-ace1-dee34a884652)

Client_Secrets. json:

{

  "installed": {
    "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
    "project_id": "testindexer",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "redirect_uris": [ "urn:ietf:wg:oauth:2.0:oob", "http://localhost" ]
  }
}


using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;


namespace AzureFunctionToUploadToYoutube
{
    public static class Function1
    {
        [FunctionName("Function1")]

        public static async Task Run([BlobTrigger("video/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, Microsoft.Azure.WebJobs.ExecutionContext context, ILogger log)
        {
            log.LogInformation("Function triggered by blob." + name);
            UserCredential credential;
            log.LogInformation("Getting client secrets.");

            using (var stream = new FileStream(System.IO.Path.Combine(context.FunctionAppDirectory, "client_secrets.json"), FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                new[] { YouTubeService.Scope.YoutubeUpload },
                "user",
                CancellationToken.None
                new FileDataStore("Google.Apis.Auth.OAuth2.Responses.TokenResponse-use",true)
                );
            }
            log.LogInformation("Done getting secrets.");
            log.LogInformation("Creating youtube service");

            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
            });

            log.LogInformation("Done creating service.");
            var video = new Video();
            video.Snippet = new VideoSnippet();
            video.Snippet.Title = name;
            video.Snippet.Description = "Seattle Channel";
            video.Snippet.Tags = new string[] { "tag1", "tag2" };
            video.Snippet.CategoryId = "22";
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = "unlisted";
            var VideoInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", myBlob, "video/*");

            log.LogInformation("Trying to upload video");

            try
            {
                await VideoInsertRequest.UploadAsync();
                log.LogInformation("Done uploading video.");
            }

            catch (Exception ex)
            {
                log.LogInformation("Error uploading video: " + ex.Message);
            }
        }
    }
}

1 Ответ

1 голос
/ 31 марта 2020

GoogleWebAuthorizationBroker.AuthorizeAsyn c

Для установленных приложений. Он открывает окно веб-браузера авторизации на компьютере, на котором он работает с вашей функцией Azure, не может открыть окно веб-браузера, и даже если вы не можете войти на сервер, на котором он работает, и аутентифицировать его.

решение

аутентифицируйте код один раз на вашем компьютере. Go в папку% appdata% на windows и найдите файл учетных данных. Установите FileDataStore для загрузки из местоположения, которое может понять ваша функция. Filedatastore демистилируется и загружает файл с вашим кодом.

filedatastore

Filedatastore используется для хранения учетных данных, возвращаемых пользователем по умолчанию, не включает его, и файл будет храниться в% appdata%. Вы можете указать местоположение. или нет места, и он "должен" go в текущем каталоге.

Важно то, что библиотека, если она обнаружит файл, будет загружать учетные данные в этом файле, а не запрашивать вход в систему, что именно и должно происходить в этом случае.

using (var stream = new FileStream(System.IO.Path.Combine(context.FunctionAppDirectory, "client_secrets.json"), FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                new[] { YouTubeService.Scope.YoutubeUpload },
                "user",
                CancellationToken.None,
                new FileDataStore("credfolder",true)                              

                );
            } 

IDatastore.

Если вы все еще не можете заставить его работать, единственный другой вариант, о котором я могу подумать, - это создать собственную реализацию Idatastore, которая позволит вам передавать значения из файла учетных данных непосредственно в код, а не чем сохранить его в файл. Обратите внимание, что вам нужно всего лишь отправить токен refre sh. У меня нет такого примера, но у меня есть несколько примеров того, как создать вашу собственную реализацию idatastore, это может помочь вам разобраться в этом Систе Datastores

...