Youtube v3 api 401 未经授权 [英] Youtube v3 api 401 Unauthorized
问题描述
我正在尝试使用 youtube api 的 v3 上传文件,而不使用 c# 库.我真的无法使用该库,因为我正在制作自己的库,该库允许我使用一些常见的 api(youtube、vimeo、facebook 等)
I am trying to upload a file using v3 of the youtube api and without using the c# library. I really can't use the library because I am making my own library that allows me to use a few common apis (youtube, vimeo, facebook, etc)
我已经获得了访问令牌和刷新令牌,这很好.现在我需要使用此处定义的 youtube 可恢复上传上传文件:
I have already got my access token and refresh token which is fine. Now I need to upload a file using the youtube resumable uploads defined here:
https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol
但由于某种原因,我的代码返回 401 Unauthorized 错误,但我不明白为什么.这是我创建请求的代码:
but for some reason my code is coming back with a 401 Unauthorized error but I can't see why. Here is my code that is creating the request:
private void CreateUploadRequest(SynchronisedAsset asset)
{
var endPoint = api.ApiUrl + "/videos?uploadType=resumable&part=snippet&key=" + api.Tokens.ConsumerKey; // read for the different ways to interact with videos https://developers.google.com/youtube/v3/docs/#Videos
var maxSize = 68719476736; // 64 gig
try
{
var location = CompanyProvider.GetUploadLocation(this.baseUploadDirectory, companyId, FileType.Asset);
var filePath = System.IO.Path.Combine(location, asset.FileName);
using (var data = new FileStream(filePath, FileMode.Open))
{
if (maxSize > data.Length && (asset.MimeType.ToLower().StartsWith("video/") || asset.MimeType.ToLower().Equals("application/octet-stream")))
{
var json = "{ \"snippet\": { \"title\": \"" + asset.FileName + "\", \"description\": \"This is a description of my video\" } }";
var buffer = Encoding.ASCII.GetBytes(json);
var request = WebRequest.Create(endPoint);
request.Headers[HttpRequestHeader.Authorization] = string.Format("Bearer {0}", api.Tokens.AccessToken);
request.Headers["X-Upload-Content-Length"] = data.Length.ToString();
request.Headers["X-Upload-Content-Type"] = asset.MimeType;
request.ContentType = "application/json; charset=UTF-8";
request.ContentLength = buffer.Length;
request.Method = "POST";
using (var stream = request.GetRequestStream())
{
stream.Write(buffer, 0, (int)buffer.Length);
}
var response = request.GetResponse();
}
}
}
catch (Exception ex)
{
eventLog.WriteEntry("Error uploading to youtube.\nEndpoint: " + endPoint + "\n" + ex.ToString(), EventLogEntryType.Error);
}
}
api.ApiUrl 是 https://www.googleapis.com/youtube/v3.我不确定是否需要密钥,它没有在文档中显示,但我添加了它以查看是否可以解决我的未授权问题.另外,我想如果没有密钥,它怎么知道要上传到哪个帐户?
api.ApiUrl is https://www.googleapis.com/youtube/v3. I am not sure if the key is needed, it doesn't show it in the documentation but I added it to see if I could solve my Unauthorized issue. Also, I figured that without the key, how would it know what account to upload to?
谁能看到我的代码有什么问题?
Can anyone see what is wrong with my code?
任何帮助将不胜感激.
更新 1
在整理了一些东西之后,我现在添加了一些代码,用于在尝试上传之前检查 youtube 凭据.这是通过这些代码位完成的:
After a bit of time sorting stuff out, I have now added some code that checks the youtube credentials before trying to do an upload. This is done with these bits of code:
public string GetAuthorizeApplicationUrl()
{
var sb = new StringBuilder();
var dictionary = new Dictionary<string, string>
{
{"client_id", Tokens.ConsumerKey},
{"redirect_uri", callbackUrl},
{"response_type", "code"},
{"scope", "https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtubepartner"},
{"approval_prompt", "force"},
{"access_type", "offline"},
{"state", ""}
};
sb.Append(requestTokenUrl);
foreach (var parameter in dictionary)
{
var query = (sb.ToString().Contains("?")) ? "&" : "?";
sb.Append(query + parameter.Key + "=" + parameter.Value);
}
return sb.ToString();
}
这段代码负责构建允许我们请求用户访问的 URL.
This bit of code is responsible for building the URL that allows us to ask the user for access.
对于返回到我们的返回 URL 的代码,我们称之为这段代码:
With the code that is returned to our return URL we call this bit of code:
public void RequestAccessToken(string code)
{
var dictionary = new Dictionary<string, string>
{
{"code", code},
{"client_id", Tokens.ConsumerKey},
{"client_secret", Tokens.ConsumerSecret},
{"redirect_uri", callbackUrl},
{"grant_type", "authorization_code"}
};
var parameters = NormalizeParameters(dictionary);
var resultString = "";
using (var wc = new WebClient())
{
//wc.Headers[HttpRequestHeader.Host] = "POST";
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
resultString = wc.UploadString(requestAccessTokenUrl, parameters);
}
var json = JObject.Parse(resultString);
Tokens.AccessToken = json["access_token"].ToString();
Tokens.RefreshToken = (json["refresh_token"] != null) ? json["refresh_token"].ToString() : null;
Tokens.Save(companyId);
}
现在因为我们已经将我们的应用声明为离线,所以当我们进行任何 api 调用时,我们可以只使用这段代码:
Now because we have declared our app as offline, when we do any api calls we can just use this bit of code:
public bool CheckAccessToken()
{
try
{
RefreshToken(); // Get and store our new tokens
return true;
}
catch
{
return false;
}
}
private void RefreshToken()
{
var dictionary = new Dictionary<string, string>
{
{"refresh_token", Tokens.RefreshToken},
{"client_id", Tokens.ConsumerKey},
{"client_secret", Tokens.ConsumerSecret},
{"grant_type", "refresh_token"}
};
var parameters = NormalizeParameters(dictionary);
var resultString = "";
using (var wc = new WebClient())
{
//wc.Headers[HttpRequestHeader.Host] = "POST";
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
resultString = wc.UploadString(requestAccessTokenUrl, parameters);
}
var json = JObject.Parse(resultString);
Tokens.AccessToken = json["access_token"].ToString();
Tokens.Save(companyId);
}
在我的 Windows 服务中,我有这个代码:
In my windows service I have this code:
public void SynchroniseAssets(IEnumerable<SynchronisedAsset> assets)
{
if (api.CheckAccessToken())
{
foreach (var asset in assets)
{
var uploadAssetThread = new Thread(() => CreateUploadRequest(asset));
uploadAssetThread.Start(); // Upload our assets at the same time
}
}
}
如您所见,它调用了上面的原始代码.将其解析为 json 时遇到的错误是:
which as you can see calls the Original code above. The error which I am getting when I parse it into json is this:
{
"error":{
"errors":[
{
"domain":"youtube.header",
"reason":"youtubeSignupRequired",
"message":"Unauthorized",
"locationType":"header",
"location":"Authorization"
}
],
"code":401,
"message":"Unauthorized"
}
}
所以,如果有人能帮我弄清楚这意味着什么,那就太好了.
So, if anyone could help me work out what that means, that would be great.
干杯,
/r3plica
推荐答案
返回 401 Unautorized 的问题是因为我获得访问权限的帐户没有与之关联的 YouTube 帐户.
The issue returning 401 Unautorized was because the account I was gaining access to did not have a youtube account associated with it.
这篇关于Youtube v3 api 401 未经授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!