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 服务