YouTube 数据 API V3 - 自动化授权过程而不是人工干预
YouTube Data API V3 - automate authorisation process instead of manual intervention
我正在使用 YouTube 数据 API V3 将视频上传到我的 YouTube 频道。提供的示例代码中的授权代码需要在授权过程中手动干预。每次我重新启动服务器时,它都会打开浏览器并要求我进行身份验证和权限。对于我的 Windows PC,没问题,但我要将此代码部署到我只有 SSH 访问权限的远程 Linux 机器上。
有没有办法让这个过程自动进行?就像使用普通凭据(用户名和密码)访问 API 或进行一次此过程(永久 authentication/authorisation)一样。
我确实阅读了一些关于此主题的主题,其中指出使用刷新令牌。
通常我会说您应该使用服务帐户,然后您根本不需要执行身份验证过程。但是 YouTube API 不支持服务帐户身份验证。
我无法解释为什么您的身份验证需要在重启后刷新。您的代码应该保存包含刷新令牌的凭据文件,刷新令牌即使在重新启动后也应该继续工作。我猜你的代码有问题。
这是一个 Java Quickstart 示例,显示了如何保存凭据。它是为 api 而不是 Youtube 的人准备的,如果您需要任何帮助来为 YouTube 修改它,请告诉我。重新启动服务器时不会删除这些凭据。
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.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.people.v1.PeopleService;
import com.google.api.services.people.v1.PeopleScopes;
import com.google.api.services.people.v1.model.ListConnectionsResponse;
import com.google.api.services.people.v1.model.Person;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME =
"People API Java Quickstart";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(
System.getProperty("user.home"), ".credentials/people.googleapis.com-java-quickstart");
/** Global instance of the {@link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/** Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
* at ~/.credentials/people.googleapis.com-java-quickstart
*/
private static final List<String> SCOPES =
Arrays.asList(PeopleScopes.CONTACTS_READONLY);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
* @return an authorized Credential object.
* @throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
InputStream in =
Quickstart.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();
Credential credential = new AuthorizationCodeInstalledApp(
flow, new LocalServerReceiver()).authorize("user");
System.out.println(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized People client service.
* @return an authorized People client service
* @throws IOException
*/
public static PeopleService getPeopleService() throws IOException {
Credential credential = authorize();
return new PeopleService.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public static void main(String [] args) throws IOException {
PeopleService service = getPeopleService();
// Request 10 connections.
ListConnectionsResponse response = service.people().connections()
.list("people/me")
.setPageSize(10)
.setPersonFields("names,emailAddresses")
.execute();
// Print display name of connections if available.
List<Person> connections = response.getConnections();
if (connections != null && connections.size() > 0) {
for (Person person : connections) {
List<Name> names = person.getNames();
if (names != null && names.size() > 0) {
System.out.println("Name: " + person.getNames().get(0)
.getDisplayName());
} else {
System.out.println("No names available for connection.");
}
}
} else {
System.out.println("No connections found.");
}
}
}
答:关于你的服务器问题以及如何让它自动。答案是你不能。没有浏览器 window 无法进行身份验证。您应该在 windows 电脑上进行身份验证,将我提到的凭据文件复制到您的服务器。
您如何存储凭据?如果您的服务器关闭,您的凭据是否也会随之丢失?您可以考虑将其存储在外部数据库中,或者如果它是网络应用程序,您可以将其存储为 cookie。
刷新令牌仅颁发一次(在第一次初始身份验证期间),因此如果您之前已经授权过您的帐户,则需要访问您的应用权限并将其删除。然后再次尝试授权,并保存该刷新令牌。如果您正确保存了刷新令牌(使用 cookies/database/whatever),那么您将根据请求获得一个新的访问令牌。使用此方法,不用每次都重新授权
可能有点晚了...
1) 在 Google Developers Console 中创建新项目。
2) 创建 oauth 2.0 客户端 ID。在申请类型 select - 其他。
3) 下载 json 文件,将其重命名为 "client_secret.json" 并将其添加到 /resources 文件夹(对于 Gradle 项目)。
4) 创建 java 文件并添加此代码:
public class YoutubeAuth {
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 FileDataStoreFactory dataStoreFactory;
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/youtube");
private static final String APPLICATION_NAME = "Custom Application Name";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/**
* Create an authorized Credential object.
*
* @return an authorized Credential object.
* @throws IOException
*/
private static Credential authorize(final NetHttpTransport httpTransport) throws IOException {
// Load client secrets.
InputStream in = YoutubeAuth.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)
.setDataStoreFactory(dataStoreFactory)
.build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
/**
* 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();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorize(httpTransport);
return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
}
注意这行代码:
private static FileDataStoreFactory dataStoreFactory;
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),".store/youtube");
并在 authorize() 方法中使用此方法:
.setDataStoreFactory(dataStoreFactory)
以及 getService() 方法中的此方法:
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
YouTube youtubeService = LfkYoutubeAuth.getService();
...
// some other code
---
所以你可以像这样使用 Youtube 服务
我正在使用 YouTube 数据 API V3 将视频上传到我的 YouTube 频道。提供的示例代码中的授权代码需要在授权过程中手动干预。每次我重新启动服务器时,它都会打开浏览器并要求我进行身份验证和权限。对于我的 Windows PC,没问题,但我要将此代码部署到我只有 SSH 访问权限的远程 Linux 机器上。
有没有办法让这个过程自动进行?就像使用普通凭据(用户名和密码)访问 API 或进行一次此过程(永久 authentication/authorisation)一样。
我确实阅读了一些关于此主题的主题,其中指出使用刷新令牌。
通常我会说您应该使用服务帐户,然后您根本不需要执行身份验证过程。但是 YouTube API 不支持服务帐户身份验证。
我无法解释为什么您的身份验证需要在重启后刷新。您的代码应该保存包含刷新令牌的凭据文件,刷新令牌即使在重新启动后也应该继续工作。我猜你的代码有问题。
这是一个 Java Quickstart 示例,显示了如何保存凭据。它是为 api 而不是 Youtube 的人准备的,如果您需要任何帮助来为 YouTube 修改它,请告诉我。重新启动服务器时不会删除这些凭据。
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.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.people.v1.PeopleService;
import com.google.api.services.people.v1.PeopleScopes;
import com.google.api.services.people.v1.model.ListConnectionsResponse;
import com.google.api.services.people.v1.model.Person;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME =
"People API Java Quickstart";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(
System.getProperty("user.home"), ".credentials/people.googleapis.com-java-quickstart");
/** Global instance of the {@link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/** Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
* at ~/.credentials/people.googleapis.com-java-quickstart
*/
private static final List<String> SCOPES =
Arrays.asList(PeopleScopes.CONTACTS_READONLY);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
* @return an authorized Credential object.
* @throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
InputStream in =
Quickstart.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();
Credential credential = new AuthorizationCodeInstalledApp(
flow, new LocalServerReceiver()).authorize("user");
System.out.println(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized People client service.
* @return an authorized People client service
* @throws IOException
*/
public static PeopleService getPeopleService() throws IOException {
Credential credential = authorize();
return new PeopleService.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public static void main(String [] args) throws IOException {
PeopleService service = getPeopleService();
// Request 10 connections.
ListConnectionsResponse response = service.people().connections()
.list("people/me")
.setPageSize(10)
.setPersonFields("names,emailAddresses")
.execute();
// Print display name of connections if available.
List<Person> connections = response.getConnections();
if (connections != null && connections.size() > 0) {
for (Person person : connections) {
List<Name> names = person.getNames();
if (names != null && names.size() > 0) {
System.out.println("Name: " + person.getNames().get(0)
.getDisplayName());
} else {
System.out.println("No names available for connection.");
}
}
} else {
System.out.println("No connections found.");
}
}
}
答:关于你的服务器问题以及如何让它自动。答案是你不能。没有浏览器 window 无法进行身份验证。您应该在 windows 电脑上进行身份验证,将我提到的凭据文件复制到您的服务器。
您如何存储凭据?如果您的服务器关闭,您的凭据是否也会随之丢失?您可以考虑将其存储在外部数据库中,或者如果它是网络应用程序,您可以将其存储为 cookie。
刷新令牌仅颁发一次(在第一次初始身份验证期间),因此如果您之前已经授权过您的帐户,则需要访问您的应用权限并将其删除。然后再次尝试授权,并保存该刷新令牌。如果您正确保存了刷新令牌(使用 cookies/database/whatever),那么您将根据请求获得一个新的访问令牌。使用此方法,不用每次都重新授权
可能有点晚了...
1) 在 Google Developers Console 中创建新项目。
2) 创建 oauth 2.0 客户端 ID。在申请类型 select - 其他。
3) 下载 json 文件,将其重命名为 "client_secret.json" 并将其添加到 /resources 文件夹(对于 Gradle 项目)。
4) 创建 java 文件并添加此代码:
public class YoutubeAuth {
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 FileDataStoreFactory dataStoreFactory;
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/youtube");
private static final String APPLICATION_NAME = "Custom Application Name";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/**
* Create an authorized Credential object.
*
* @return an authorized Credential object.
* @throws IOException
*/
private static Credential authorize(final NetHttpTransport httpTransport) throws IOException {
// Load client secrets.
InputStream in = YoutubeAuth.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)
.setDataStoreFactory(dataStoreFactory)
.build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
/**
* 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();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorize(httpTransport);
return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
}
注意这行代码:
private static FileDataStoreFactory dataStoreFactory;
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),".store/youtube");
并在 authorize() 方法中使用此方法:
.setDataStoreFactory(dataStoreFactory)
以及 getService() 方法中的此方法:
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
YouTube youtubeService = LfkYoutubeAuth.getService();
...
// some other code
---
所以你可以像这样使用 Youtube 服务