了解为什么通过curl上传视频会返回身份验证错误
我正试图通过API上传到YouTube。我正在使用了解为什么通过curl上传视频会返回身份验证错误,curl,google-api,google-oauth,youtube-data-api,Curl,Google Api,Google Oauth,Youtube Data Api,我正试图通过API上传到YouTube。我正在使用curl执行此操作,当我运行以下命令时,我收到一个错误,表示我未经身份验证,即使我已经填写了身份验证详细信息 我的代码是: curl -XPOST -H 'client_id: CLIENT_ID' -H 'client_secret: CLIENT_SECRET' -H 'auth_uri: https://accounts.google.com/o/oauth2/auth' -H 'token_uri: https://oauth2.goog
curl
执行此操作,当我运行以下命令时,我收到一个错误,表示我未经身份验证,即使我已经填写了身份验证详细信息
我的代码是:
curl -XPOST -H 'client_id: CLIENT_ID' -H 'client_secret: CLIENT_SECRET' -H 'auth_uri: https://accounts.google.com/o/oauth2/auth' -H 'token_uri: https://oauth2.googleapis.com/token' -H "Content-type: application/json" -d '{
"snippet": {
"title": "Test Title",
"description": "Test description",
"tags": ["test", "tags"],
"categoryId": 20
},
"status": {
"privacyStatus": "unlisted"
}
}' 'https://www.googleapis.com/upload/youtube/v3/videos'
错误消息是401
:
请求缺少所需的身份验证凭据。预期的OAuth 2访问令牌、登录cookie或其他有效身份验证凭据。看
我100%正确地输入了
客户id
和客户机密
。不幸的是,@Mac Hooper,你的代码有很多问题。请容忍我一会儿:
此请求需要至少具有以下作用域之一的授权() 范围
https://www.googleapis.com/auth/youtube.upload
https://www.googleapis.com/auth/youtube
https://www.googleapis.com/auth/youtubepartner
https://www.googleapis.com/auth/youtube.force-ssl
B一次性上传
curl
在shell脚本中实现此协议
另一方面,如果希望每次视频上传只发出一个curl
呼叫(不包括获取访问令牌的过程中隐含的呼叫),则必须一次性上传视频。但是,这个curl
调用需要事先做好某些准备
在一次上传中使用curl
时,有一个指示路径
基本上,您的curl
调用如下所示:
$curl\
--数据二进制“@$MULTIPART_相关”\
--标题“内容类型:$Content\u Type”\
--标题“授权:持有人$ACCESS\u令牌”\
'https://www.googleapis.com/upload/youtube/v3/videos?uploadType=multipart&part=snippet,地位'
(请注意,上面我假定在bash
命令行提示符下发出curl
。在Windows命令行提示符下,情况类似,但应适当调整上面的curl
命令。)
上面的curl
命令有三个参数:$MULTIPART\u RELATED
、$CONTENT\u TYPE
和$ACCESS\u TOKEN
。后者是传递到YouTube服务器上的凭证数据,以便
请阅读官方文档的部分,了解如何在成功完成OAuth 2身份验证/授权流后获得有效(未过期)的访问令牌
参数$MULTIPART\u RELATED
是在发出实际的curl
调用之前应该(以编程方式)编写的文件名。这个文件的格式并没有正式的文档记录,而是在检查谷歌自己的开源代码后得到的
参数$CONTENT\u TYPE
是一个字符串,指定通过curl
发布的HTTPPOST
方法所需的值
同样,对于SO问题,提供了能够正确生成文件
$MULTIPART\u RELATED
和字符串$CONTENT\u TYPE
的所有详细信息。如果您查看文档,您将找到一个示例,说明如何在curl中进行上传
curl --request POST \
'https://youtube.googleapis.com/youtube/v3/videos?key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{}' \
--compressed
您似乎缺少一些头,这些头主要是作为承载令牌传递的访问令牌所需的头。您需要了解的是,client\u id
和client\u secret
用于创建访问令牌,它们本身并不授予您访问任何数据的权限
需要使用Oauth2流创建访问令牌。我有一个例子来说明如何做到这一点。您需要使用https://www.googleapis.com/auth/youtube.upload
范围
# Client id from Google Developer console
# Client Secret from Google Developer console
# Scope this is a space seprated list of the scopes of access you are requesting.
# Authorization link. Place this in a browser and copy the code that is returned after you accept the scopes.
https://accounts.google.com/o/oauth2/auth?client_id=[Application Client Id]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=[Scopes]&response_type=code
# Exchange Authorization code for an access token and a refresh token.
curl \
--request POST \
--data "code=[Authentcation code from authorization link]&client_id=[Application Client Id]&client_secret=[Application Client Secret]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" \
https://accounts.google.com/o/oauth2/token
# Exchange a refresh token for a new access token.
curl \
--request POST \
--data 'client_id=[Application Client Id]&client_secret=[Application Client Secret]&refresh_token=[Refresh token granted by second step]&grant_type=refresh_token' \
https://accounts.google.com/o/oauth2/token
抱歉,@DaImTo,但是你误导了OP(很可能你不是一个有经验的API用户)。第一个
curl
命令失败,出现以下错误响应:{“error”:{“code”:400,“message”:“请求不包括视频内容。”,“errors”:[{“message”:“请求不包括视频内容。”,“domain”:“youtube.video”,“reason”:“mediaBodyRequired”,“location”:“body”,“locationType”:“other”}}}
。由于第一个curl
命令不会上载任何类型的视频内容,因此API错误响应是正确的。请阅读我对这篇文章的回答(几天前我确实提供了),了解如何通过一个curl
命令上传视频文件。另一方面,使用URL上的post
方法https://youtube.googleapis.com/youtube/v3/videos
是未记录的API(即使它应该以某种方式工作)。也就是说,尽管API explorer在API explorer窗口上的curl
命令下显示URL,该命令可在端点的官方页面上访问。只有一件(次要)事情(可能会让没有经验的API用户感到困惑):当向API端点提供访问令牌以发出授权请求时,与访问令牌一起使用API密钥是多余的(只需传递给API即可)