ASP.NET Core - The OAuth YouTube Data API Dance

Table of Contents

alt=“working with YouTube data api process flow”

Introduction

YouTube Data API allows developers to add YouTube features to their applications. Using the API, a developer can upload and search for videos among many other features on behalf of the YouTube channel owner. In this post, we start by creating a Google project so that we can acquire credentials to access the YouTube API. We then create a Razor Pages application and use HTTP/REST to call the OAuth 2.0 endpoints. The Razor Pages application user feedback will rely on the logging output from the Visual Studio Code Debug Console for feedback.

Prerequisites

  • A Google account (not a Brand Account) and an existing YouTube Channel. Though not necessary, a verified account will allow you to upload videos larger than 15 minutes, add custom thumbnails among other features.

  • Downloaded and installed the .NET SDK (Software Development Kit). You need .NET SDK to create the Razor Pages application.

  • A text editor for editing source code. We will be using Visual Studio Code but you are free to follow along using your favourite editor.

The YouTube Data API Dance

We can broadly break down the process of working with the YouTube Data API into two phases:

A. Configure Google YouTube Data API project

The following are steps to complete this phase:

  1. Create a Google application project. A project is a grouping of settings and API access information.

  2. Enable YouTube Data API v3 service

  3. Configure User Consent Screen for the YouTube channel owner authorization.

  4. Create OAuth client Credentials.

B. Using YouTube Data API In Your Application.

  1. Create ASP.NET Core Razor Pages application

  2. Request Temporary Authorization Code

  3. Exchange Authorization Code With Access Token

  4. Use access token to upload videos

A. Configure Google YouTube Data API Project

Create Google Project

  1. Navigate to create new project page.

  2. Google generates a project name and project ID for you. You can customize the project name and ID or accept the suggested values. Take note that you cannot change a project’s ID after creation. For this post, let’s name the project as YouTubeApiTest.

alt=“YouTube Data API test project”

  1. Click on CREATE button. A notification dialog appears when the project creation completes. Click on VIEW link on the notifications dialog. This will take you to the project’s page.

  2. Click on the hamburger menu (top left of page preceding the Google APIs logo) and select APIs & Services > Library. This will display a listing of Google APIs. Scroll down and select YouTube Data API v3 and click on ENABLE button to enable YouTube Data API v3.

alt=""

You can also search for the YouTube Data API by typing in the search box.

alt=“YouTube APIs Search”

Before an application can use the YouTube Data API to upload videos on behalf of the YouTube channel’s owner, the owner has to grant an authorization. Google authorization server presents a consent request to the owner. The owner may allow or cancel the consent; authorization needs to happen only once.

  1. Click on Credentials from sidebar menu or on CREATE CREDENTIALS button.

  2. Click on CONFIGURE CONSENT SCREEN button.

  3. Under User Type, select External and then click on CREATE button. An internal app is restricted to G Suite users while an external one is available to any user with a Google Account. Clicking the create button will open a new page where you can provide further information about the application.

alt=""

  1. Type your Application Name. You can use the same name as your project’s name (YouTubeApiTest) or type a more descriptive name

  2. Provide a logo for your application. This step is optional. If you however add or modify a logo, your consent screen will require verification by Google. Take note that no option exists for removing a logo. You can however schedule a project for deletion (shut down) after 30 days.

  3. Under Scopes for Google APIs, click on Add scope button. Select YouTube Data API v3 which has a description of Manage your YouTube videos and click on ADD button. Scopes grant an applications different levels of access on behalf of the end user.

alt=“add project scopes”

  1. Scroll down and click on Save button. After the saving process has completed, a summary page of the project with its limitations displays.

Create OAuth client Credentials

When using an application on behalf of a user to upload videos, edit playlists or anything that would require a user log in, authorized access using an OAuth 2.0 workflow is required (Client Id and a Secret Key). In situations where your interest would be only in searching for publicly available videos and playlists, then an API key would have been the most appropriate.

  1. Click on Credentials on the sidebar menu

  2. Click on + CREATE CREDENTIALS (at top of page) and select OAuth client ID.

  3. Under Application type, select an application type. Select Web application. alt=“application type options”

  4. Type a name for the application or use the value of the suggested application name.

  5. Under Authorized redirect URIs, click on + ADD URI button. Redirect URIs will be the endpoints where the authorizing server will redirect responses from the YouTube Data API for errors, authorization code and access tokens. For this post, our redirect will be https://localhost:5001/videos/upload?handler=authorize. alt=“authorization server redirect uris”

  6. Click on CREATE button. This will display an OAuth client created modal window. alt=“youtube data api oauth client created”

  7. Click OK to close the OAuth client created confirmation window

  8. Under OAuth 2.0 Client IDs section, select the client ID you have created and click on the download file icon (far right) to download the Client OAuth ID json file. After the download completes, rename the file to client_secrets.json. You can use a different name or use the assigned name.

alt=“download client id json file”

That concludes the first phase of setting up the YouTube Data API project.

B. Using YouTube Data API In Your Application

Create ASP.NET Core Razor Pages Application

  1. Open a Terminal window and navigate to the location where you wish to create your project

  2. Create a Razor project by running the following command dotnet new razor -o YouTubeApiTest

  3. Open the project by running code YouTubeApiTest.

  4. Click Yes when the Required assets to build and debug are missing from ‘YouTubeApiTest’. Add them? dialog is displayed.

Create Video Upload Page

  1. Create a Videos folder within the Pages folder. This is not mandatory; you can create the upload page in a folder of your liking. For this post, we will place files related to the YouTube upload in this folder.

  2. Create Upload.cshtml content page within the Videos folder. This first line of the file will contain @page {handler?} directive. This will allow us to access the upload route using https://localhost:5001/videos/upload or using the optional method handler https://localhost:5001/videos/upload/authorize. Update the file with the following code:

  3. Create a new a page model file Upload.cshtml.cs. This file will contain code relating to processing of user input data. Update the file using the following code:

  4. Just for aesthetics, let’s update wwwroot\css\site.css with the following:

  5. Open \Pages\Shared_Layout.cshtml layout page and add a link for opening the YouTube uploads page.

  6. Run the project by selecting Run > Run Without Debugging from the menu or by pressing Ctrl + F5 and click on YouTube link to open the the videos upload page alt=“YouTube video upload test page”

Request Temporary Authorization Code

The request for the temporary authorization code will require approval from the owner of the YouTube channel. For this to happen, we redirect the request for the code to Google Authorization Server. A redirect will include the user credentials contained in the JSON file we downloaded when we created the Google project in the first phase. Request for the code will only be necessary if no token file exists.

  1. If you did not download the OAuth credentials file, download the file, copy/move it to the root of the project and rename to client_secrets.json. If you are using a version control system for the project, make sure to exclude the file from versioning.

  2. Create OAuthClientInfo.cs file at the root of the project. We will use this class to read and store the contents of the client_secrets.json. Update the file using following code:

  3. Open the terminal window and add the YouTube Data API package to the project by running dotnet add package Google.Apis.YouTube.v3 command.

  4. Within Upload.cshtml.cs page model file, add a OnGetRequestCode() method. This method will read the contents of the OAuth credentials file and use the contained values to authenticate and request an authorization code from the Google Authorization server. When the user allows the authorization, the authorization server will return a temporary authorization code (response_type). A cancellation of authorization will return an error. Google authorization server will send the error or temporary authorization code response to the redirect_url we specified during Google project creation. Setting access_type to offline will ensure our application can refresh access tokens without the user being present at the browser.

We require to create a constant for the token file name const string TOKEN_FILE = "youtube_token.json"; and add using System.Linq;, using System;, using System.Collections.Generic;, using Microsoft.AspNetCore.WebUtilities; and using Google.Apis.YouTube.v3; namespaces to the page model.

Exchange Authorization Code With Access Token

This step is dependant on the owner/user of the YouTube channel granting or denying access to our application. If the owner cancels the request, Google authorization server sends an error response to our application’s redirect uri and the story ends there. If on the other hand the owner allows access, we parse the authorization code from the query string of the response, exchange the authorization code for a short-lived (one hour) access token and long-lived (six months) refresh token and persist these to a file for future retrieval and usage.

  1. Create the redirect URI endpoint by adding a OnGetAuthorize handler method within the Upload.cshtml.cs file.

  2. Add code to handle error responses. The code will also log the errors so we can get feedback on the errors.

  3. Let’s test errors can hit our redirect URI. Run the project, click on the YouTube link and finally click Request authorization code button. On the Sign in with Google page, select your account. A warning This app isn’t verified page appears. Click Advanced > Go to YouTube API Test (unsafe). Click on Cancel. You get returned to the video upload page and an error log entry will appear on the DEBUG CONSOLE. alt=“access denied error log”

  4. Before we can write code to handle exchanging the authorization code for a token, we need to make some changes to Startup.cs in the root of the project. We need to add services.AddHttpClient(); to the ConfigureServices. This will enable us to make requests using HttpClient.

  5. The next change will be in the constructor of the upload page model (Upload.cshtml.cs). Replace the current constructor method signature with public UploadModel(ILogger<UploadModel> logger, IHttpClientFactory clientFactory, IWebHostEnvironment hostingEnvironment), import required namespaces (using System.Net.Http; and using Microsoft.AspNetCore.Hosting;) and add relevant field variables. IWebHostEnvironment will be used in generation of the token file name.

  6. Add code within OnGetAuthorize method for extracting the authorization code from the request. The code calls ExchangeCodeForTokenAsync which we will add in the next step.

  7. Add a method ExchangeCodeForTokenAsync which will request for the code/token exchange and on success, persist the token data to a token file. This method will require you import using System.Text; namespace in order to use UTF8 encoding.

  8. Run the project, click on the YouTube link and finally click Request authorization code button. Follow the process we performed above while testing for errors but this time click on Allow button so that the authorization server can grant an authorization code. When the process completes, you will see authorization code granted and Token exchanged with access token messages on the DEBUG CONSOLE. Also, within project’s root folder, youtube_token.json file will is created. alt=“exchange authorization code with token log”

The following are the contents of the token file:

We will use the access_token to make requests to YouTube Data API for authorization. Note that any application code that shares the same client ID and secret pair can use the same access token. The access token will expire after one hour after which we will renew the token using the refresh_token.

A refresh token may also become invalid under the following conditions:

  • The user has revoked the application’s access.
  • The refresh token remains unused for six months.
  • The user changed passwords and the refresh token contains Gmail scopes.
  • Granted refresh tokens for the user’s account have been exceeded (limited to 50 refresh tokens per user account per client).
  • a new refresh token has been granted

Use Access Token To Upload Videos

The final step will be using the access token to upload YouTube videos. This step will involve selecting the video you wish to upload, providing the title and description for the video and clicking on the upload video button.

When the upload video button gets clicked, we fetch the video data and persist the video file data in a temporary file. Next we fetch and validate the token. If the token is no longer valid, we obtain a new token using the refresh token. Finally, we use the YouTube Data API and delete the temporary video file.

  1. To persist the video file to a temporary file, create a field variable private string _tempFilePath; within Upload.cshtml.cs for the filename and then override the OnPageHandlerExecuting page filter. This method will get called after model binding but before the code for video uploading runs. You will also require to import the following namespaces, System.IO and Microsoft.AspNetCore.Mvc.Filters.

  2. Create a OnPostAsync handler method. This handler method gets invoked when the uploaded video button gets clicked. This handler method calls various support methods to perform different tasks.

GetVideoData does nothing much except creating an instance of YouTube video. It requires importation of the Google.Apis.YouTube.v3.Data namespace.

FetchToken reads token data from the token file, validates the token and if not valid fetches a new token using the refresh token. This method relies on IsValid and RefreshToken helper methods. The method requires System.Threading.Tasks, System.Text.Json and Google.Apis.Auth.OAuth2.Responses namespaces.

IsValid validates the token with the Google Authorization server. If the response does not contain an error_description then the token is valid.

The RefreshToken method gets called only if the persisted token is not valid. Using the user credentials and the refresh token, the method requests for a new token from the Google Authorization server and persist the new token to a file replacing the invalid token.

FetchYouTubeService creates an instance of the YouTubeService which we use to upload the selected video. This method requires the importation of Google.Apis.Auth.OAuth2.Flows, Google.Apis.Auth.OAuth2, Google.Apis.Services and System.Reflection namespaces.

Finally, we register a ProgressChanged changed event (will require importation of Google.Apis.Upload namespace) to monitor the upload process

and ResponseReceived event which gets invoked after video upload completes. After video upload completes, we delete the temporary video file.

To test uploading videos, run the application, open the YouTube videos upload page, search for the video you want to upload, complete title and description of the video and click on the Video upload button. Make sure to select a video that does not exceed 28.6MB otherwise you will end up getting a BadHttpRequestException:Request body too large exception.

alt=“video upload progress”

That brings us to the end of uploading YouTube videos using HTTP/REST and I hope the post has been helpful.