如何在Express.js中通过服务账户获取Google Photos相册JSON列表?
解决方案
问题分析
你当前的代码存在两个核心问题:
- 错误使用了OAuth2授权码流程的客户端对象,服务账户应该用JWT认证而非普通OAuth2客户端
- 前端直接调用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
相关产品推荐
相关产品推荐

