从使用 YouTube 数据 API 的个人项目中删除 Google 未经验证的警告
Posted
技术标签:
【中文标题】从使用 YouTube 数据 API 的个人项目中删除 Google 未经验证的警告【英文标题】:Removing Google unverified warning from personal project that uses the YouTube Data API 【发布时间】:2021-01-12 03:30:54 【问题描述】:我正在制作一个不供公众使用的个人项目。该项目使用 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:
我不确定 localhost 是什么以及数字代表什么,所以我用星号替换了它,以防它应该是私有的。
当我打开下面的链接时,系统会提示我登录我的 Google 帐户,然后显示此屏幕。
此应用未经验证 此应用尚未经过 Google 验证。只有在您了解并信任开发者的情况下才能继续。
如果您是开发者,请提交验证请求以移除此屏幕。了解更多
Google 尚未审核此应用,因此无法确认其真实性。未经验证的应用程序可能会对您的个人数据构成威胁。了解更多
我不想经历整个验证过程,因为这本身并不是一个真正的“应用程序”。我只是在玩弄 API 来了解它是如何工作的。有什么方法可以绕过验证过程,这样我就可以使用 API 进行练习,而无需让 Google 批准我制作的随机项目?我不想每次使用该程序时都必须在线登录。
编辑
如果我正确理解 cmets,我每次运行程序时都必须登录的原因是因为我使用 OAuth 2.0,而我只需要使用 API 密钥,因为我的程序不需要访问我的特定帐户。 authorization credentials 页面上强烈暗示了这一点,该页面指出:
此 API 支持两种类型的凭据。创建适合您项目的凭据:
OAuth 2.0:每当您的应用程序请求私有用户数据时,它必须随请求一起发送 OAuth 2.0 令牌。您的应用程序首先发送一个客户端 ID,并且可能还发送一个客户端密码以获取令牌。您可以为 Web 应用程序、服务帐户或已安装的应用程序生成 OAuth 2.0 凭据。
API 密钥:不提供 OAuth 2.0 令牌的请求必须发送 API 密钥。密钥标识您的项目并提供 API 访问、配额和报告。
当我第一次创建项目时,我只打算使用 API 密钥,而不是 OAuth 2.0 凭据,因为它在该页面上显示。但是,Java quickstart 没有提供仅使用 API 密钥的选项。相反,那里显示的演示代码看起来像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 密钥而不是包含我的 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();
问题已解决。
【问题讨论】:
只需点击Go to GradleDemo (Unsafe)
。
@stvar 对不起,如果我不清楚;我将编辑我的问题以澄清。我正在寻找某种方式来运行程序,而无需先上网登录。
这在设计上是不可能的。您必须登录一次——从 API 获取(长期)刷新令牌和(短期)访问令牌。那么就不需要再登录了,除非你丢弃了之前获得的刷新令牌。但是当您打算只读取公共视频元数据时,OAuth 2.0 授权不是必需的。 W.r.t.刷新/访问令牌确实读取了top-level description of them I gave a while ago,然后开始吸收其中提到的文档。
@stvar 我已经编辑了我的问题。我不确定我说的是否正确,但我相信这可能会更容易解决问题。
【参考方案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 令牌,否则必填。覆盖:
setKey
在课堂上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
(对象)变量。
【讨论】:
以上示例中的youtube.apikey
是什么?它是实际数字键、文件名或其他内容的替代品吗?
如果您查看代码,您会看到 API 密钥是从名为 youtube.properties
的 properties 文件中读取的。这对您来说并不是真正必要的,但除此之外,这是一个很好的做法(不要让您的 API 密钥在源代码本身中出现)。您可能只是拥有类似request.setKey(YOUR_APP_KEY)
的东西,其中YOUR_APP_KEY
的类型为String
,并拥有您从Google 获得的API 密钥。
我改变了我的主要方法,见上面的编辑。还没有解决我的问题,每次运行代码我还是要登录。
但是您仍然调用 getService
(您保持不变),这将启动 OAuth 流程。
我引用的示例代码没有像 authorize
这样的调用,它本身会启动 OAuth 流程。以上是关于从使用 YouTube 数据 API 的个人项目中删除 Google 未经验证的警告的主要内容,如果未能解决你的问题,请参考以下文章
访问未配置。 YouTube 数据 API 尚未在项目 608941808256 中使用