java - 从使用 YouTube 数据 API 的个人项目中删除 Google 未经验证的警告

标签 java oauth-2.0 youtube youtube-api youtube-data-api

我正在制作一个不供公众使用的个人项目。该项目使用 YouTube 数据 API v3。当我运行代码时,我看到了这个警告:

> Task :ApiExample.main()
2020-09-25 14:52:25.740:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2020-09-25 14:52:25.748:INFO::jetty-6.1.26
2020-09-25 14:52:25.796:INFO::Started SocketConnector@localhost:*****
Please open the following address in your browser:
我不确定本地主机是什么以及数字代表什么,所以我用星号替换了它,以防它应该是私有(private)的。
当我打开下面的链接时,系统会提示我登录我的 Google 帐户,然后显示此屏幕。
Google Verification Warning

This app isn't verified This app hasn't been verified by Google yet. Only proceed if you know and trust the developer.


If you’re the developer, submit a verification request to remove this screen. Learn more


Google hasn't reviewed this app yet and can't confirm it's authentic. Unverified apps may pose a threat to your personal data. Learn more


我不想经历整个验证过程,因为这本身并不是一个真正的“应用程序”。我只是在玩弄 API 来了解它是如何工作的。有什么方法可以绕过验证过程,这样我就可以使用 API 进行练习,而无需让 Google 批准我制作的随机项目?我不想每次使用该程序时都必须在线登录。
编辑
如果我正确理解评论,我每次运行程序时都必须登录的原因是因为我只需要使用 API key ,因为我的程序不需要访问我的特定帐户,所以我使用的是 OAuth 2.0。 authorization credentials 强烈暗示了这一点。页面,其中指出:

This API supports two types of credentials. Create whichever credentials are appropriate for your project:


OAuth 2.0: Whenever your application requests private user data, it must send an OAuth 2.0 token along with the request. Your application first sends a client ID and, possibly, a client secret to obtain a token. You can generate OAuth 2.0 credentials for web applications, service accounts, or installed applications.


API keys: A request that does not provide an OAuth 2.0 token must send an API key. The key identifies your project and provides API access, quota, and reports.


当我第一次创建项目时,我只打算使用 API key ,而不是 OAuth 2.0 凭据,因为它在那个页面上说了什么。但是,Java quickstart没有提供仅使用 API key 的选项。相反,那里显示的演示代码看起来像 this :
/**
 * Sample Java code for youtube.channels.list
 * See instructions for running these code samples locally:
 * https://developers.google.com/explorer-help/guides/code_samples#java
 */

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
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.ChannelListResponse;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Collection;

public class ApiExample {
    private static final String CLIENT_SECRETS= "client_secret.json";
    private static final Collection<String> SCOPES =
        Arrays.asList("https://www.googleapis.com/auth/youtube.readonly");

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

    /**
     * Create an authorized Credential object.
     *
     * @return an authorized Credential object.
     * @throws IOException
     */
    public static Credential authorize(final NetHttpTransport httpTransport) throws IOException {
        // Load client secrets.
        InputStream in = ApiExample.class.getResourceAsStream(CLIENT_SECRETS);
        GoogleClientSecrets clientSecrets =
          GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow =
            new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
            .build();
        Credential credential =
            new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
        return credential;
    }

    /**
     * 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();
        Credential credential = authorize(httpTransport);
        return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
            .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 and execute the API request
        YouTube.Channels.List request = youtubeService.channels()
            .list("snippet,contentDetails,statistics");
        ChannelListResponse response = request.setId("UC_x5XG1OV2P6uZZ5FSM9Ttw").execute();
        System.out.println(response);
    }
}
在上面的代码示例中,client_secret.json是包含我的 OAuth 2.0 凭据的 JSON 文件。所以,说了这么多,我相信我可以将我的问题重申如下:如何仅使用 API key 而不是包含我的 OAuth 2.0 凭据的 JSON 文件来编写上述代码示例?
编辑
我已经更换了我的 main方法如下:
public static void main(String[] args)
        throws GeneralSecurityException, IOException, GoogleJsonResponseException {
    Properties properties = new Properties();
    try {
        InputStream in = ApiExample.class.getResourceAsStream("/" + "youtube.properties");
        properties.load(in);

    } catch (IOException e) {
        System.err.println("There was an error reading " + "youtube.properties" + ": " + e.getCause()
                + " : " + e.getMessage());
        System.exit(1);
    }
    YouTube youtubeService = getService();
    // Define and execute the API request
    YouTube.Channels.List request = youtubeService.channels()
            .list("snippet,contentDetails,statistics");
    String apiKey = properties.getProperty("youtube.apikey");
    request.setKey(apiKey);
    ChannelListResponse response = request.setId("UC_x5XG1OV2P6uZZ5FSM9Ttw").execute();
    System.out.println(response);

}
但是,每当我运行代码时,我仍然必须登录。
编辑
哎呀,我还在打getService()上述代码示例中的方法。以下作品:
YouTube youtubeService = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer() {
            public void initialize(HttpRequest request) throws IOException {
            }
        }).setApplicationName(APPLICATION_NAME).build();
问题已解决。

最佳答案

如果您只打算使用 Channels.list 用于获取公共(public) channel 元数据的 API 端点,那么绝对不需要使用 OAuth 2.0 授权(以及隐含的一次性身份验证)。YouTube.Channels.list类有这个方法,它允许你设置由谷歌(通过其云控制台)提供的 API key (作为私有(private)数据):

setKey

public YouTube.Channels.List setKey(java.lang.String key)

Description copied from class: YouTubeRequest
API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.

Overrides: setKey in class YouTubeRequest<ChannelListResponse>


您可以查看示例源文件 GeolocationSearch.java 从谷歌查看setKey在行动:
// Set your developer key from the {{ Google Cloud Console }} for
// non-authenticated requests. See:
// {{ https://cloud.google.com/console }}
String apiKey = properties.getProperty("youtube.apikey");
search.setKey(apiKey);
在您的情况下,上面的代码将以完全相同的方式工作。只是你必须申请setKey给您的request (对象)变量。

关于java - 从使用 YouTube 数据 API 的个人项目中删除 Google 未经验证的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64070166/

相关文章:

java - try/catch/finally block 中的执行顺序与 try block 中的复合返回语句

java - Java 应用程序会因 -Xdebug 的存在而变慢还是仅在单步执行代码时变慢?

java - 如何在beans.xml中使用@JsonPropertyOrder注释

javascript - 这个 javascript oauth 调用可以在 POSTMAN 中表示吗? (或c#)

Spring Security OAuth 2.0 - 授权代码授予始终需要客户端 secret

video - 在iframe中循环播放youtube视频

java - 为什么 java.util.Collections.swap(List<?>, int, int) 中没有警告?

android - 当我从其他计算机上的存储库克隆项目时 Ionic2 出错

android - 自定义 Android WebView 以在内部打开除 YouTube 链接之外的所有链接

api - 使用 Youtube Player API 嵌入多个 iframe