You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Express.js中通过服务账户获取Google Photos相册JSON列表?

解决方案

问题分析

你当前的代码存在两个核心问题:

  1. 错误使用了OAuth2授权码流程的客户端对象,服务账户应该用JWT认证而非普通OAuth2客户端
  2. 前端直接调用Google Photos API时没有携带有效认证令牌,且不符合你"服务端完成全部认证"的需求

正确实现步骤

1. 服务端JWT认证配置

使用googleapis提供的JWT客户端完成服务账户认证,无需回调地址,直接用服务账户密钥生成令牌:

const express = require('express');
const { google } = require('googleapis');
const config = require('./你的配置文件路径'); // 替换为实际配置文件路径

const app = express();

// 初始化JWT客户端
const jwtClient = new google.auth.JWT(
  config.serviceAccount.client_email,
  null,
  config.serviceAccount.private_key,
  ['https://www.googleapis.com/auth/photoslibrary.readonly'], // 只读权限足够满足需求
  null // 普通账户留null;G Suite域用户需填写要模拟的域内用户邮箱(需先开启域范围委派)
);

// 预完成认证
async function authenticate() {
  try {
    await jwtClient.authorize();
    console.log('服务账户认证成功');
  } catch (err) {
    console.error('认证失败:', err);
  }
}

authenticate();

2. 编写Express路由获取相册列表

在服务端完成Google Photos API调用,前端仅需请求自己的后端接口即可获取数据:

// 前端可访问的相册列表接口
app.get('/api/albums', async (req, res) => {
  try {
    const photos = google.photoslibrary({
      version: 'v1',
      auth: jwtClient
    });

    const response = await photos.albums.list({
      pageSize: 50, // 可调整每页返回的相册数量上限
    });

    const albums = response.data.albums || [];
    // 整理需要的字段:ID、标题、访问链接等
    const formattedAlbums = albums.map(album => ({
      id: album.id,
      title: album.title,
      productUrl: album.productUrl,
      mediaCount: album.mediaItemsCount
    }));

    res.json(formattedAlbums);
  } catch (err) {
    console.error('获取相册失败:', err);
    res.status(500).json({ error: '无法获取相册列表' });
  }
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});

3. 前端请求后端接口

前端不再直接调用Google的API,改为请求自己的后端路由:

function getAlbumList(){
    var xhr = new XMLHttpRequest();
    var url = "/api/albums" // 指向自己的后端接口
    xhr.open("GET",url,true);

    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            const albums = JSON.parse(xhr.responseText);
            console.log('相册列表:', albums);
            // 在这里处理数据,比如渲染到页面
        }
    }
    xhr.addEventListener('error',function(){
        console.log("请求失败,状态码:", xhr.status );
        console.log("错误信息:", xhr.statusMessage);
    })
    xhr.send();
}

关键注意事项

  • 共享相册给服务账户:服务账户没有独立的Google Photos存储空间,必须手动将需要访问的相册共享给服务账户邮箱(即配置中的client_email字段值)
  • 权限范围:使用photoslibrary.readonly只读权限即可,避免申请不必要的权限
  • 域范围委派(可选):仅G Suite管理员可用,需在Admin Console中为服务账户启用该功能,才能访问域内用户的相册;普通Google账户只能通过共享相册方式访问

内容的提问来源于stack exchange,提问作者user311302

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 00:10:49