最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating a YouTube Service via ASP.NET using a pre-existing Access Token - Stack Overflow

programmeradmin0浏览0评论

I've been working on a Website for users to upload videos to a shared YouTube account for later access. After much work I've been able to get an Active Token, and viable Refresh Token.

However, the code to initialize the YouTubeService object looks like this:

UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets, 
        // This OAuth 2.0 access scope allows an application to upload files to the
        // authenticated user's YouTube channel, but doesn't allow other types of access.
        new[] { YouTubeService.Scope.YoutubeUpload },
        "user",
        CancellationToken.None
    );
}

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

I've already got a token, and I want to use mine. I'm using ASP.NET version 3.5, and so I can't do an async call anyways.

Is there any way I can create a YouTubeService object without the async call, and using my own token? Is there a way I can build a credential object without the Authorization Broker?

Alternatively, the application used YouTube API V2 for quite some time, and had a form that took a token, and did a post action against a YouTube URI that was generated alongside the token in API V2. Is there a way I can implement that with V3? Is there a way to use Javascript to upload videos, and possibly an example that I could use in my code?

I've been working on a Website for users to upload videos to a shared YouTube account for later access. After much work I've been able to get an Active Token, and viable Refresh Token.

However, the code to initialize the YouTubeService object looks like this:

UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets, 
        // This OAuth 2.0 access scope allows an application to upload files to the
        // authenticated user's YouTube channel, but doesn't allow other types of access.
        new[] { YouTubeService.Scope.YoutubeUpload },
        "user",
        CancellationToken.None
    );
}

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

I've already got a token, and I want to use mine. I'm using ASP.NET version 3.5, and so I can't do an async call anyways.

Is there any way I can create a YouTubeService object without the async call, and using my own token? Is there a way I can build a credential object without the Authorization Broker?

Alternatively, the application used YouTube API V2 for quite some time, and had a form that took a token, and did a post action against a YouTube URI that was generated alongside the token in API V2. Is there a way I can implement that with V3? Is there a way to use Javascript to upload videos, and possibly an example that I could use in my code?

Share Improve this question edited May 16, 2017 at 2:58 Vadim Ovchinnikov 14k7 gold badges65 silver badges94 bronze badges asked Apr 28, 2015 at 21:28 Troy GTroy G 4453 silver badges13 bronze badges 5
  • If you are using framework 3.5 then the library with async calls will not work, it should be piled against fw 4.0 or higher... – Gusman Commented Apr 28, 2015 at 23:27
  • Yep. That is why I want a solution that doesn't rely on the async calls. I don't want to upgrade the framework if I don't absolutely have to. – Troy G Commented Apr 29, 2015 at 4:56
  • Oh my god - it's 2017 and I'm running into the same thing. Did you ever figure this out? – user677526 Commented May 10, 2017 at 0:05
  • To clarify - the same problem, but for different reasons; I'm attempting to do some of this work in the cloud where there isn't a UI. However, I should already have an access token ing in with my request. – user677526 Commented May 10, 2017 at 0:16
  • I did figure out how to programatically initialize a UserCredential object. I'll post my code in an answer because it is too long for a ment. – Troy G Commented May 10, 2017 at 14:44
Add a ment  | 

2 Answers 2

Reset to default 4

NOTE: I ended up upgrading my Framework to 4.5 to access the google libraries.

To programatically initialize a UserCredential Object you've got to build a Flow, and TokenResponse. A Flow Requires a Scope (aka the permissions we are seeking for the credentials.

using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Auth.OAuth2.Flows;

string[] scopes = new string[] {
    YouTubeService.Scope.Youtube,
    YouTubeService.Scope.YoutubeUpload
};

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
    ClientSecrets = new ClientSecrets
    {
        ClientId = XXXXXXXXXX,  <- Put your own values here
        ClientSecret = XXXXXXXXXX  <- Put your own values here
    },
    Scopes = scopes,
    DataStore = new FileDataStore("Store")
});

TokenResponse token = new TokenResponse {
    AccessToken = lblActiveToken.Text,
    RefreshToken = lblRefreshToken.Text
};

UserCredential credential = new UserCredential(flow, Environment.UserName, token);

Hope that helps.

Currently the official Google .NET client library does not work with .NET Framework 3.5. (Note: this is an old question the library hasn't supported .NET 3.5 since 2014. So the statement would have been valid then as well.) That being said you are not going to be able to create a service for the Google .NET client library using an existing access token. Also not possible to create it with an access token using any .NET Framework you would need to create your own implementation of Idatastore and load a refresh token.

Supported Platforms

  1. .NET Framework 4.5 and 4.6
  2. .NET Core (via netstandard1.3 support)
  3. Windows 8 Apps
  4. Windows Phone 8 and 8.1
  5. Portable Class Libraries

That being said you are going to have to code this yourself from the ground up. I have done it and it is doable.

Authentication :

You have stated you have your refresh token already so I won't go into how to create that. The following is a HTTP POST call

Refresh access token request:

https://accounts.google./o/oauth2/token 
client_id={ClientId}.apps.googleusercontent.&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token

Refresh Access token response:

{ "access_token" : "ya29.1.AADtN_XK16As2ZHlScqOxGtntIlevNcasMSPwGiE3pe5ANZfrmJTcsI3ZtAjv4sDrPDRnQ", "token_type" : "Bearer", "expires_in" : 3600 }

An call you make to the YouTube API you can either add the access token as the authorization bearer token or you can just take it on to the end of any request

https://www.googleapis./youtube/v3/search?access_token={token here}

I have a full post on all of the calls to the auth server Google 3 legged Oauth2 flow. I just use normal webRequets for all my calls.

// Create a request for the URL.
WebRequest request = WebRequest.Create("http://www.contoso./default.html");  
// If required by the server, set the credentials.  
request.Credentials = CredentialCache.DefaultCredentials;  
// Get the response.
WebResponse response = request.GetResponse();  
// Display the status.
Console.WriteLine (((HttpWebResponse)response).StatusDescription);  
// Get the stream containing content returned by the server.  
Stream dataStream = response.GetResponseStream();  
// Open the stream using a StreamReader for easy access.  
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.  
Console.WriteLine(responseFromServer);  
// Clean up the streams and the response.  
reader.Close();  
response.Close();

Upgrade .NET 4+

If you can upgrade to the newest version of .NET using the library will be much easier. This is from Googles official documentation Web Applications ASP.NET. I have some additional sample code on my github account which shoes how to use the Google Drive API. Google dotnet samples YouTube data v3.

using System;
using System.Web.Mvc;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Mvc;
using Google.Apis.Drive.v2;
using Google.Apis.Util.Store;

namespace Google.Apis.Sample.MVC4
{
    public class AppFlowMetadata : FlowMetadata
    {
        private static readonly IAuthorizationCodeFlow flow =
            new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId = "PUT_CLIENT_ID_HERE",
                        ClientSecret = "PUT_CLIENT_SECRET_HERE"
                    },
                    Scopes = new[] { DriveService.Scope.Drive },
                    DataStore = new FileDataStore("Drive.Api.Auth.Store")
                });

        public override string GetUserId(Controller controller)
        {
            // In this sample we use the session to store the user identifiers.
            // That's not the best practice, because you should have a logic to identify
            // a user. You might want to use "OpenID Connect".
            // You can read more about the protocol in the following link:
            // https://developers.google./accounts/docs/OAuth2Login.
            var user = controller.Session["user"];
            if (user == null)
            {
                user = Guid.NewGuid();
                controller.Session["user"] = user;
            }
            return user.ToString();

        }

        public override IAuthorizationCodeFlow Flow
        {
            get { return flow; }
        }
    }
}

Top tip YouTube doesn't support service accounts your going to have to stick with Oauth2. As long as you have authenticated your code once it should continue to work.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>