移除个人项目中使用YouTube Data API出现的Google未验证警告。

huangapple go评论136阅读模式
英文:

Removing Google unverified warning from personal project that uses the YouTube Data API

问题

我正在进行一个个人项目,不打算公开使用。该项目使用YouTube Data API v3。当我运行代码时,我看到以下警告:

> Task :ApiExample.main()
2020年9月25日 14:52:25.740:INFO::通过 org.mortbay.log.StdErrLog 记录到 STDERR
2020年9月25日 14:52:25.748:INFO::jetty-6.1.26
2020年9月25日 14:52:25.796:INFO::已启动 SocketConnector@localhost:*****
请在浏览器中打开以下地址:

我不确定“localhost”是什么,以及数字代表什么,所以我已经用星号替换它,以防它应该是私有的。

当我打开随后的链接时,我被提示登录到我的Google账号,之后我看到了这个屏幕。

移除个人项目中使用YouTube Data API出现的Google未验证警告。

>此应用未经验证
此应用尚未经过Google的验证。只有在您了解并信任开发人员的情况下继续。

>如果您是开发人员,请提交验证请求以移除此屏幕。了解更多信息

>Google尚未审核此应用,并且无法确认其是否真实。未经验证的应用可能会对您的个人数据构成威胁。了解更多信息

我不想经历整个验证过程,因为这实际上并不是一个真正的“应用”。我只是在使用API来学习其工作原理。有没有办法绕过验证过程,以便我可以在不必让Google批准我创建的随机项目的情况下练习使用API?我不想每次使用程序时都必须在线登录。

编辑

如果我理解评论正确,我每次运行程序时需要登录的原因是因为我正在使用OAuth 2.0,但实际上我只需要使用API密钥,因为我的程序不需要访问我的特定帐户。这在授权凭据页面上已经明确表示:

>此API支持两种类型的凭证。根据您的项目创建适合您项目的凭证:

>OAuth 2.0:每当您的应用程序请求私人用户数据时,它必须随请求一起发送OAuth 2.0令牌。您的应用程序首先发送客户端ID,可能还会发送客户端秘钥以获取令牌。您可以为Web应用程序、服务帐户或安装的应用程序生成OAuth 2.0凭证。

>API密钥:不提供OAuth 2.0令牌的请求必须发送API密钥。该密钥标识您的项目并提供API访问、配额和报告。

当我首次创建项目时,我只打算使用API密钥,而不是OAuth 2.0凭证,因为页面上所述。然而,Java快速入门没有提供仅使用API密钥的选项。相反,那里显示的演示代码看起来像是这样的:[链接略]

在上述代码示例中,client_secret.json 是包含我的OAuth 2.0凭证的JSON文件。因此,基于这一切,我认为我可以重新表达我的问题如下:如何使用仅API密钥,而不是包含我的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("读取" + "youtube.properties" + " 时出错 " + e.getCause()
                + " : " + e.getMessage());
        System.exit(1);
    }
    YouTube youtubeService = getService();
    // 定义并执行API请求
    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();

问题已解决。

英文:

I am making a personal project that is not intended for public use. The project uses YouTube Data API v3. When I run the code, I see this warning:

> 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:

I'm not sure what a localhost is and what the number represents, so I have replaced it with asterisks just in case it is supposed to be private.

When I open the link that follows, I am prompted to login to my Google account, after which I am shown this screen.

移除个人项目中使用YouTube Data API出现的Google未验证警告。

>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

I don't want to go through the entire verification process, because this isn't really an "app", per se. I'm just playing around with the API to learn how it works. Is there any way to bypass the verification process so that I can practice with the API without having to have Google approve a random project that I made? I don’t want to have to login online every time I use the program.

Edit

If I understand the comments correctly, the reason why I have to login every time I run the program is because I am using OAuth 2.0 when I only need to be using an API key since my program does not need access to my particular account. This was strongly implied on the authorization credentials page, which states:

>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.

When I first created the project, I only intended to use an API key, and not OAuth 2.0 credentials because of what it says on that page. However, the Java quickstart does not give an option to use only an API key. Rather, the demo code shown there looks like 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);
    }
}

In the above code sample, client_secret.json is the JSON file that contains my OAuth 2.0 credentials. So, with all this having been said, I believe I can restate my question as follows: How do I write the above code sample using just an API key, and not a JSON file that contains my OAuth 2.0 credentials?

Edit

I've replaced my main method with the following:

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

}

However I still have to log in whenever I run the code.

Edit

Whoops, I was still calling the getService() method in the above code sample. The following works:

YouTube youtubeService = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer() {
            public void initialize(HttpRequest request) throws IOException {
            }
        }).setApplicationName(APPLICATION_NAME).build();

The issue has been resolved.

答案1

得分: 1

如果您只打算使用 Channels.list API 端点来获取公共频道元数据,那么绝对不需要使用 OAuth 2.0 授权(以及暗示的一次性身份验证)。

YouTube.Channels.list 类具有此方法,允许您设置由 Google(通过其云控制台)提供的 API 密钥(作为私密数据):

setKey

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

从类中复制的描述:YouTubeRequest
API 密钥。您的 API 密钥标识您的项目,并为您提供 API 访问权限、配额和报告。除非您提供 OAuth 2.0 令牌,否则需要此项。

覆盖:
在类 YouTubeRequest<ChannelListResponse> 中的 setKey

您可以查看来自 Google 的示例源文件 GeolocationSearch.java,以了解 setKey 的实际用法:

// 从 {{ Google Cloud 控制台 }} 获取您的开发人员密钥,用于非身份验证请求。参见:
// {{ https://cloud.google.com/console }}
String apiKey = properties.getProperty("youtube.apikey");
search.setKey(apiKey);

在您的情况下,上述代码片段将完全以相同的方式工作。只需将 setKey 应用于您的 request(对象)变量即可。

英文:

If you only intend to use the Channels.list API endpoint for to obtain public channel meta-data, then there's definitely no need to employ OAuth 2.0 authorization (and the implied one-time authentication).

The YouTube.Channels.list class has this method, that allows you to set the API key provided (as private data) by Google (via its cloud console):

> 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&lt;ChannelListResponse&gt;

You may look at the sample source file GeolocationSearch.java from Google for to see setKey in action:

// Set your developer key from the {{ Google Cloud Console }} for
// non-authenticated requests. See:
// {{ https://cloud.google.com/console }}
String apiKey = properties.getProperty(&quot;youtube.apikey&quot;);
search.setKey(apiKey);

In your case, the above piece of code will work entirely the same way. Only that you'll have to apply setKey to your request (object) variable.

huangapple
  • 本文由 发表于 2020年9月26日 03:16:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64070166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定