使用预先存在的访问令牌通过 ASP.NET 创建 YouTube 服务

Posted

技术标签:

【中文标题】使用预先存在的访问令牌通过 ASP.NET 创建 YouTube 服务【英文标题】:Creating a YouTube Service via ASP.NET using a pre-existing Access Token 【发布时间】:2015-07-07 22:39:50 【问题描述】:

我一直在开发一个网站,供用户将视频上传到共享的 YouTube 帐户以供日后访问。经过大量工作,我已经能够获得一个 Active Token 和可行的 Refresh Token。

但是,初始化YouTubeService 对象的代码如下所示:

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,
);

我已经有一个令牌,我想使用我的。我使用的是 ASP.NET 3.5 版,所以无论如何我都无法拨打async

有什么方法可以在没有async 调用的情况下创建一个YouTubeService 对象,并使用我自己的令牌?有没有一种方法可以在没有授权代理的情况下构建凭据对象?

或者,该应用程序使用 YouTube API V2 有一段时间了,并且有一个接受令牌的表单,并针对在 API V2 中与令牌一起生成的 YouTube URI 执行发布操作。有没有办法可以用 V3 实现它?有没有办法使用 javascript 来上传视频,并且可能有一个我可以在我的代码中使用的示例?

【问题讨论】:

如果您使用的是框架 3.5,那么带有异步调用的库将不起作用,它应该针对 fw 4.0 或更高版本进行编译... 是的。这就是为什么我想要一个不依赖异步调用的解决方案。如果不是绝对必要,我不想升级框架。 天哪 - 现在是 2017 年,我也遇到了同样的事情。你有想过这个吗? 澄清一下——同样的问题,但原因不同;我正在尝试在没有 UI 的云中做一些这样的工作。但是,我的请求中应该已经有一个访问令牌。 我确实弄清楚了如何以编程方式初始化 UserCredential 对象。我将在答案中发布我的代码,因为评论太长了。 【参考方案1】:

注意:我最终将我的框架升级到 4.5 以访问谷歌库。

要以编程方式初始化 UserCredential 对象,您必须构建 Flow 和 TokenResponse。一个流程需要一个范围(也就是我们为凭证寻求的权限。

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);

希望对您有所帮助。

【讨论】:

您说您使用的是 .net 3.5 谷歌 .net 客户端库与 .net 4.0 一起工作,该版本不再更新。 .net 4.5 是当前支持的目标。该库不适用于您的项目。除非你更新了框架。这也不起作用,因为 FileDatastore 需要刷新令牌才能工作,并且问题状态访问令牌。 就初始令牌而言。那很简单。我构建了一个单独的表单来植入该令牌,然后将其存储在数据库中。当需要使用它时,我会检查我的令牌过期时间,如果过期,我会通过存储的刷新令牌刷新它。 这个 lblActiveToken 和这个 lblRefreshToken 是什么?您是否从用户那里获取这些输入?我想使用我的帐户从播放列表中检索视频列表。【参考方案2】:

目前官方Google .NET client library 不适用于.NET Framework 3.5。 (注意:这是该库自 2014 年以来不支持 .NET 3.5 的一个老问题。因此该声明在那时也是有效的。) 话虽如此,您将无法使用现有访问令牌为 Google .NET 客户端库创建服务。也无法使用任何 .NET Framework 使用访问令牌创建它,您需要创建自己的 Idatastore 实现并加载刷新令牌。

支持的平台

    .NET Framework 4.5 和 4.6 .NET Core(通过 netstandard1.3 支持) Windows 8 应用程序 Windows Phone 8 和 8.1 可移植类库

话虽如此,您将不得不自己从头开始编写代码。我已经做到了,而且是可行的。

身份验证:

您已经声明您已经拥有刷新令牌,因此我不会详细说明如何创建它。 下面是一个 HTTP POST 调用

刷新访问令牌请求:

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

刷新访问令牌响应:

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

您对 YouTube API 的调用可以将访问令牌添加为授权持有者令牌,也可以将其置于任何请求的末尾

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

我有一个关于所有对身份验证服务器 Google 3 legged Oauth2 flow 的调用的完整帖子。我所有的电话都使用普通的webRequets。

// Create a request for the URL.
WebRequest request = WebRequest.Create("http://www.contoso.com/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();

升级 .NET 4+

如果您可以使用该库升级到最新版本的 .NET,将会容易得多。这是来自谷歌官方文档Web Applications ASP.NET。我的 github 帐户上有一些额外的示例代码,用于指导如何使用 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.com/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; 
        
    

重要提示 YouTube 不支持您必须坚持使用 Oauth2 的服务帐户。只要您对代码进行了身份验证,它就应该可以继续工作。

【讨论】:

忘了提 - 我实际上使用的是 .NET 4.6.2。我可以访问 SDK,但在 Web 请求方面,我似乎必须处理很多隐式行为。 我已经编辑了我的答案,添加了一些关于如何使用库的信息。你真的应该打开你自己的问题,这个问题是针对 3.5 的,所以它真的与你的问题无关。如果您需要更多帮助,请告诉我,我在 youtube 上也有一些教程。

以上是关于使用预先存在的访问令牌通过 ASP.NET 创建 YouTube 服务的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Identity(使用 IdentityServer4)获取外部资源 oauth 访问令牌

编写可通过 asp.net 身份用户和不记名令牌访问的单个 API

如何通过 AngularJS $http 从 ASP.Net Web API 2 获取访问令牌?

使用 OWIN 在 ASP.NET MVC 5 应用程序中存储和检索 facebook 访问令牌

JWT不记名令牌授权不起作用asp net core web api

如何使用 asp.net mvc 从 azure 获取访问令牌