从使用 YouTube 数据的个人项目中删除 Google 未经验证的警告 API
Removing Google unverified warning from personal project that uses the YouTube Data API
我正在制作一个不供 public 使用的个人项目。该项目使用 YouTube Data 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:
我不确定本地主机是什么以及数字代表什么,所以我将其替换为星号以防万一它应该是私有的。
当我打开随后的 link 时,系统提示我登录我的 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
我不想完成整个验证过程,因为这本身并不是真正的“应用程序”。我只是在玩弄 API 来了解它是如何工作的。有没有什么方法可以绕过验证过程,这样我就可以使用 API 进行练习,而不必 Google 批准我制作的随机项目?我不想每次使用该程序都必须在线登录。
编辑
如果我理解正确的话,我每次 运行 程序都必须登录的原因是因为我使用的是 OAuth 2.0,而我只需要使用 API 密钥因为我的程序不需要访问我的特定帐户。 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 密钥,而不是 OAuth 2.0 凭据,因为它在该页面上有说明。但是,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);
}
}
在上面的代码示例中,client_secret.json
是包含我的 OAuth 2.0 凭据的 JSON 文件。所以,说了这么多,我相信我可以重述我的问题如下:How do I write the above code sample using just an API key, and not a JSON file that contains my OAuth 2.0 凭据?
编辑
我已将 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
API端点来获取public通道meta-data,那么绝对不需要 使用 OAuth 2.0 授权(和隐含的 one-time 身份验证)。
YouTube.Channels.list
class 有这个方法,它允许你设置 Google 提供的 API 密钥(作为私有数据)(通过它的云控制台) :
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>
您可以查看 Google 中的示例源文件 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
(对象)变量。
我正在制作一个不供 public 使用的个人项目。该项目使用 YouTube Data 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:
我不确定本地主机是什么以及数字代表什么,所以我将其替换为星号以防万一它应该是私有的。
当我打开随后的 link 时,系统提示我登录我的 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
我不想完成整个验证过程,因为这本身并不是真正的“应用程序”。我只是在玩弄 API 来了解它是如何工作的。有没有什么方法可以绕过验证过程,这样我就可以使用 API 进行练习,而不必 Google 批准我制作的随机项目?我不想每次使用该程序都必须在线登录。
编辑
如果我理解正确的话,我每次 运行 程序都必须登录的原因是因为我使用的是 OAuth 2.0,而我只需要使用 API 密钥因为我的程序不需要访问我的特定帐户。 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 密钥,而不是 OAuth 2.0 凭据,因为它在该页面上有说明。但是,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);
}
}
在上面的代码示例中,client_secret.json
是包含我的 OAuth 2.0 凭据的 JSON 文件。所以,说了这么多,我相信我可以重述我的问题如下:How do I write the above code sample using just an API key, and not a JSON file that contains my OAuth 2.0 凭据?
编辑
我已将 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
API端点来获取public通道meta-data,那么绝对不需要 使用 OAuth 2.0 授权(和隐含的 one-time 身份验证)。
YouTube.Channels.list
class 有这个方法,它允许你设置 Google 提供的 API 密钥(作为私有数据)(通过它的云控制台) :
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 classYouTubeRequest<ChannelListResponse>
您可以查看 Google 中的示例源文件 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
(对象)变量。