【问题标题】:use YouTube Data API (v3) to update a video via API keys got a 401 error使用 YouTube 数据 API (v3) 通过 API 密钥更新视频时出现 401 错误
【发布时间】:2020-11-12 22:56:45
【问题描述】:

在我的 java 后端应用程序中,我想每周使用石英作业将我的 youtube 视频状态从公开更改为私人,这是一个预定的作业。所以我使用 YouTube Data API (v3) 的 Videos Update 来完成这项工作。

请参阅YouTube Data API Reference Videos: update 和代码示例Resource>videos,Method>update。 根据Obtaining authorization credentials,获取授权凭证有两种方式,一种是OAuth 2.0,另一种是使用API Keys。我选择使用API Keys 因为它比 oauth2 更简单。

我已经从 Google API 控制台检索了 API 密钥,我运行从 youtube 的文档 Resource>videos,Method>update 复制的代码示例并运行它们,它们都出现 401 错误。

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED"
  }
}

我不知道为什么我不能通过使用 API 密钥调用 videos.update 来工作。我不想使用 OAuth2,我认为使用 API Keys 是更好的方法。因为,不可能打开浏览器窗口并让用户在石英工作中进行 oauth 登录和授权,谁能告诉我什么是有问题怎么办?

代码示例如下

基于 Java

/**
 * Sample Java code for youtube.videos.update
 * See instructions for running these code samples locally:
 * https://developers.google.com/explorer-help/guides/code_samples#java
 */

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;

import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoLocalization;
import com.google.api.services.youtube.model.VideoSnippet;
import com.google.api.services.youtube.model.VideoStatus;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;

public class ApiExample {
    // You need to set this value for your code to compile.
    // For example: ... DEVELOPER_KEY = "YOUR ACTUAL KEY";
    private static final String DEVELOPER_KEY = "...";

    private static final String APPLICATION_NAME = "API code samples";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    /**
     * Build and return an authorized API client service.
     *
     * @return an authorized API client service
     * @throws GeneralSecurityException, IOException
     */
    public static YouTube getService() throws GeneralSecurityException, IOException {
        final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        return new YouTube.Builder(httpTransport, JSON_FACTORY, null)
            .setApplicationName(APPLICATION_NAME)
            .build();
    }

    /**
     * Call function to create API service object. Define and
     * execute API request. Print API response.
     *
     * @throws GeneralSecurityException, IOException, GoogleJsonResponseException
     */
    public static void main(String[] args)
        throws GeneralSecurityException, IOException, GoogleJsonResponseException {
        YouTube youtubeService = getService();
        
        // Define the Video object, which will be uploaded as the request body.
        Video video = new Video();
        
        // Add the id string property to the Video object.
        video.setId("9BByHcBGMP4");
        
        // Add the localizations object property to the Video object.
        HashMap<String, VideoLocalization> localizations = new HashMap<>();
        
        VideoLocalization esLocalization = new VideoLocalization();
        esLocalization.setDescription("Esta descripcion es en español.");
        esLocalization.setTitle("no hay nada a ver aqui");
        localizations.put("es", esLocalization);
        
        video.setLocalizations(localizations);
        
        // Add the snippet object property to the Video object.
        VideoSnippet snippet = new VideoSnippet();
        snippet.setCategoryId("22");
        snippet.setDefaultLanguage("en");
        snippet.setDescription("This description is in English.");
        String[] tags = {
            "new tags",
        };
        snippet.setTags(Arrays.asList(tags));
        snippet.setTitle("There is nothing to see here.");
        video.setSnippet(snippet);
        
        // Add the status object property to the Video object.
        VideoStatus status = new VideoStatus();
        status.setPrivacyStatus("private");
        video.setStatus(status);

        // Define and execute the API request
        YouTube.Videos.Update request = youtubeService.videos()
            .update("snippet,status,localizations", video);
        Video response = request.setKey(DEVELOPER_KEY).execute();
        System.out.println(response);
    }
}

基于Javascript

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>
 </head>
 <body>
  <script src="https://apis.google.com/js/api.js"></script>
<script>
  /**
   * Sample JavaScript code for youtube.videos.update
   * See instructions for running APIs Explorer code samples locally:
   * https://developers.google.com/explorer-help/guides/code_samples#javascript
   */

  function loadClient() {
    gapi.client.setApiKey("...");
    return gapi.client.load("https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest")
        .then(function() { console.log("GAPI client loaded for API"); },
              function(err) { console.error("Error loading GAPI client for API", err); });
  }
  // Make sure the client is loaded before calling this method.
  function execute() {
    return gapi.client.youtube.videos.update({
      "part": [
        "snippet,status,localizations"
      ],
      "resource": {
        "id": "9BByHcBGMP4",
        "snippet": {
          "categoryId": "22",
          "defaultLanguage": "en",
          "description": "This description is in English.",
          "tags": [
            "new tags"
          ],
          "title": "There is nothing to see here."
        },
        "status": {
          "privacyStatus": "private"
        },
        "localizations": {
          "es": {
            "title": "no hay nada a ver aqui",
            "description": "Esta descripcion es en español."
          }
        }
      }
    })
        .then(function(response) {
                // Handle the results here (response.result has the parsed body).
                console.log("Response", response);
              },
              function(err) { console.error("Execute error", err); });
  }
  gapi.load("client");
</script>
<button onclick="loadClient()">load</button>
<button onclick="execute()">execute</button>

 </body>
</html>

【问题讨论】:

    标签: youtube-api youtube-data-api


    【解决方案1】:

    根据您自己引用的the official doc,要调用Videos.update API 端点,您需要获得适当的授权:

    Authorization

    此请求需要至少具有以下范围之一的授权 (read more about authentication and authorization)。

    范围

    https://www.googleapis.com/auth/youtubepartner
    https://www.googleapis.com/auth/youtube
    https://www.googleapis.com/auth/youtube.force-ssl

    因此,您无法避免在应用中使用 OAuth 2.0 身份验证/授权流程。请注意,API 密钥用于只读公共数据


    对于您的问题部分:

    [...] 不可能打开浏览器窗口并让用户在石英作业中进行 oauth 登录和授权 [...]

    API 有解决方案。请阅读以下两个文档:OAuth 2.0 for Mobile & Desktop AppsUsing OAuth 2.0 for Web Server Applications

    the answer 提供了一个简短的顶级描述,我最近回答了一个类似的问题。该答案可能会帮助您更轻松地了解解决问题的方法。

    【讨论】:

    • 是的,我知道 oauth2 是这种方式,这种调用视频的方式。更新是使用 Oauth2.0,另一种使用 API Keys 的方式似乎不需要。你的意思是代码示例已经过时了?见developers.google.com/youtube/v3/code_samples/code_snippets
    • 我不会依赖 hot 代码示例,而是依赖官方文档的信件。通常,当一个人只想玩 API 调用时,他/她应该使用这些原始工具:curlwget
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 2017-06-14
    • 2014-02-01
    • 2013-05-16
    • 2021-10-15
    • 2016-03-18
    • 1970-01-01
    相关资源
    最近更新 更多