javascript 在2023年使用谷歌照片API

yrefmtwq  于 2023-01-19  发布在  Java
关注(0)|答案(1)|浏览(113)

有人能举例说明如何在2023年使用google photos API吗?我之所以指定年份,是因为如果我试图搜索相关文档,最终会找到一个photos.get(来自google),其中包含示例代码,当我运行它时,会出现一个错误,说明文档化的方法已经过时:

"You have created a new client application that uses libraries for user
authentication or authorization that will soon be deprecated. New clients must
use the new libraries instead; existing clients must also migrate before these
libraries are deprecated. See the [Migration
Guide](https://developers.google.com/identity/gsi/web/guides/gis-migration) for
more information."

我正在尝试弄清楚如何在Javascript中使用这个API端点来访问公共Google Photos相册的内容:
https://photoslibrary.googleapis.com/v1/albums/{albumId}
看起来对于公共相册来说这应该是相当直接的,但是到目前为止看起来需要oauth,即使是访问公共相册。
有这么难吗?

ruarlubt

ruarlubt1#

您遇到的问题是,您使用的示例来自旧的JavaScript登录/授权库。
谷歌已经把它拆分了,现在你需要使用Authorizing for Web,因为你可以猜到谷歌有很多样本需要更新,我怀疑他们是否更新了所有的东西。
我已经创建了一个快速入门。请确保您在谷歌开发者控制台上创建了web应用程序凭据并创建了api密钥。

<!DOCTYPE html>
<html>
<head>
    <title>Photos API Quickstart</title>
    <meta charset="utf-8" />
</head>
<body>
<p>Photos API Quickstart</p>

<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize_button" onclick="handleAuthClick()">Authorize</button>
<button id="signout_button" onclick="handleSignoutClick()">Sign Out</button>

<pre id="content" style="white-space: pre-wrap;"></pre>

<script type="text/javascript">
    /* exported gapiLoaded */
    /* exported gisLoaded */
    /* exported handleAuthClick */
    /* exported handleSignoutClick */

    // TODO(developer): Set to client ID and API key from the Developer Console
    const CLIENT_ID = '[REDACTED]';
    const API_KEY = '[REDACTED]';

    // Discovery doc URL for APIs used by the quickstart
    const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/photoslibrary/v1/rest';

    // Authorization scopes required by the API; multiple scopes can be
    // included, separated by spaces.
    const SCOPES = 'https://www.googleapis.com/auth/photoslibrary.readonly';

    let tokenClient;
    let gapiInited = false;
    let gisInited = false;

    document.getElementById('authorize_button').style.visibility = 'hidden';
    document.getElementById('signout_button').style.visibility = 'hidden';

    /**
     * Callback after api.js is loaded.
     */
    function gapiLoaded() {
        gapi.load('client', initializeGapiClient);
    }

    /**
     * Callback after the API client is loaded. Loads the
     * discovery doc to initialize the API.
     */
    async function initializeGapiClient() {
        await gapi.client.init({
            apiKey: API_KEY,
            discoveryDocs: [DISCOVERY_DOC],
        });
        gapiInited = true;
        maybeEnableButtons();
    }

    /**
     * Callback after Google Identity Services are loaded.
     */
    function gisLoaded() {
        tokenClient = google.accounts.oauth2.initTokenClient({
            client_id: CLIENT_ID,
            scope: SCOPES,
            callback: '', // defined later
        });
        gisInited = true;
        maybeEnableButtons();
    }

    /**
     * Enables user interaction after all libraries are loaded.
     */
    function maybeEnableButtons() {
        if (gapiInited && gisInited) {
            document.getElementById('authorize_button').style.visibility = 'visible';
        }
    }

    /**
     *  Sign in the user upon button click.
     */
    function handleAuthClick() {
        tokenClient.callback = async (resp) => {
            if (resp.error !== undefined) {
                throw (resp);
            }
            document.getElementById('signout_button').style.visibility = 'visible';
            document.getElementById('authorize_button').innerText = 'Refresh';
            await listAlbums();
        };

        if (gapi.client.getToken() === null) {
            // Prompt the user to select a Google Account and ask for consent to share their data
            // when establishing a new session.
            tokenClient.requestAccessToken({prompt: 'consent'});
        } else {
            // Skip display of account chooser and consent dialog for an existing session.
            tokenClient.requestAccessToken({prompt: ''});
        }
    }

    /**
     *  Sign out the user upon button click.
     */
    function handleSignoutClick() {
        const token = gapi.client.getToken();
        if (token !== null) {
            google.accounts.oauth2.revoke(token.access_token);
            gapi.client.setToken('');
            document.getElementById('content').innerText = '';
            document.getElementById('authorize_button').innerText = 'Authorize';
            document.getElementById('signout_button').style.visibility = 'hidden';
        }
    }

    /**
     * Print metadata for first 10 Albums.
     */
    async function listAlbums() {
        let response;
        try {
            response = await gapi.client.photoslibrary.albums.list({
                'pageSize': 10,
                'fields': 'albums(id,title)',
            });
        } catch (err) {
            document.getElementById('content').innerText = err.message;
            return;
        }
        const albums = response.result.albums;
        if (!albums || albums.length == 0) {
            document.getElementById('content').innerText = 'No albums found.';
            return;
        }
        // Flatten to string to display
        const output = albums.reduce(
            (str, album) => `${str}${album.title} (${album.id}\n`,
            'albums:\n');
        document.getElementById('content').innerText = output;
    }
</script>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
</body>
</html>

公共相册。

问题是你说你的公开专辑后,如果专辑实际上是公开的,那么你应该能够摆脱只使用api密钥。你应该只需要授权,如果它的私人用户数据。
更新:经过一番挖掘,我甚至不确定这个库是否只允许您使用api密钥登录,而不发送有效的客户端ID。我已经向身份团队发送了一封电子邮件,看看他们是否有可以分享的东西。
更新:
我收到了团队的消息:
即使要访问用户向所有人提供的内容,也需要客户端ID。
因此,即使数据是公共的,您也必须注册一个客户端ID并请求用户的权限。

相关问题