如何将Google Sheets API用作数据库?JS应用读写与OAuth2问题
嘿,我完全懂你现在的头疼——想用Google Sheets当Web应用的数据库,读写还得做格式校验,关键是要把表格锁得死死的,只有可信用户能通过你的应用访问,结果碰上个OAuth2,官方文档绕得人晕头转向。我来一步步帮你把这事捋清楚,从配置到代码,再到权限控制,都是实际踩过坑的经验。
第一步:选对身份验证方式(推荐服务账号,完美适配你的场景)
先给你掰明白:你要的是应用本身拥有表格的操作权限,用户通过你的应用间接访问,表格本身不对任何外部用户开放,这种场景下用服务账号比OAuth2用户授权靠谱100倍——不需要用户自己跳Google授权页面,也能彻底锁死表格的直接访问权限。
配置服务账号的步骤
- 打开Google Cloud控制台,创建一个新项目,然后启用「Google Sheets API」(搜索就能找到)
- 在「IAM与 admin」→「服务账号」里创建一个新的服务账号,随便起个名字比如“Sheet操作机器人”
- 给这个服务账号创建密钥:点「添加密钥」→「创建新密钥」,选JSON格式,下载下来(这个文件绝对不能上传到GitHub或者前端代码里,藏好!)
- 打开你的目标Google表格,点击右上角「共享」,把服务账号的邮箱(就是JSON文件里的
client_email字段)加进去,权限设为「编辑」(要写入的话必须给编辑权限) - 把表格的共享设置里的其他无关人员全部删掉,确保只有这个服务账号能访问表格
后端代码实现(Node.js为例,必须后端处理!)
前端绝对不能碰服务账号密钥,所以所有读写操作都得通过你的后端API来做。先装依赖:
npm install googleapis express
然后写核心代码:
const { google } = require('googleapis'); const express = require('express'); const app = express(); app.use(express.json()); // 加载服务账号密钥(建议用环境变量存密钥内容,不要直接读文件) const auth = new google.auth.GoogleAuth({ keyFile: './your-service-account-key.json', // 替换成你的密钥文件路径 scopes: ['https://www.googleapis.com/auth/spreadsheets'], }); // 初始化Sheets客户端 const sheets = google.sheets({ version: 'v4', auth }); // 1. 读取表格数据+格式校验 app.get('/api/get-sheet-data', async (req, res) => { try { const spreadsheetId = '你的表格ID'; // 表格URL里的那串长字符 const range = 'Sheet1!A:C'; // 要读取的范围,比如Sheet1的A到C列 // 调用API读取数据 const response = await sheets.spreadsheets.values.get({ spreadsheetId, range, }); const rows = response.data.values; if (!rows || rows.length === 0) { return res.status(404).json({ message: '表格里还没数据呢' }); } // 格式校验示例:假设第一列是数字ID,第二列是字符串名称,第三列是日期 const invalidRows = []; rows.forEach((row, index) => { if (index === 0) return; // 跳过表头 const [id, name, date] = row; // 校验规则:ID必须是数字,名称不能为空,日期要合法 if (isNaN(Number(id)) || !name.trim() || isNaN(Date.parse(date))) { invalidRows.push({ 行号: index + 1, 数据: row }); } }); res.json({ 有效数据: rows.filter((_, idx) => idx === 0 || !invalidRows.some(r => r.行号 === idx + 1)), 无效数据: invalidRows }); } catch (err) { console.error('读取表格出错:', err); res.status(500).json({ message: '读取失败', 错误信息: err.message }); } }); // 2. 写入数据到表格(先做用户身份校验!) app.post('/api/write-sheet-data', async (req, res) => { // 第一步:先验证当前用户是不是可信用户! // 比如你可以用JWT token: // const userToken = req.headers.authorization?.split(' ')[1]; // if (!你的验证函数(userToken)) { // return res.status(403).json({ message: '你没权限操作哦' }); // } try { const spreadsheetId = '你的表格ID'; const range = 'Sheet1!A:C'; const newData = req.body.data; // 前端传过来的二维数组,比如[[1, "张三", "2024-01-01"]] // 先做数据格式校验,和读取时的规则一致 const invalidRows = []; newData.forEach((row, index) => { const [id, name, date] = row; if (isNaN(Number(id)) || !name.trim() || isNaN(Date.parse(date))) { invalidRows.push({ 行号: index + 1, 数据: row }); } }); if (invalidRows.length > 0) { return res.status(400).json({ message: '数据格式不对', 无效数据: invalidRows }); } // 调用API追加数据到表格末尾 const response = await sheets.spreadsheets.values.append({ spreadsheetId, range, valueInputOption: 'RAW', // 直接写入原始值,不解析公式 resource: { values: newData }, }); res.json({ message: '写入成功!', 新增行数: response.data.updates.updatedRows }); } catch (err) { console.error('写入表格出错:', err); res.status(500).json({ message: '写入失败', 错误信息: err.message }); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`服务器跑在端口${PORT}啦`); });
关于OAuth2用户授权(不太适合你的场景,但还是说清楚)
如果你之前尝试的是OAuth2用户授权,那是用来让用户用自己的Google账号授权,操作他们自己的表格的。但你的需求是共用一份表格,这种方式的问题是:用户必须有表格的直接访问权限,他们就能自己打开表格,不符合你“锁死表格”的需求。所以除非你要让用户操作自己的表格,否则别用这个方式。
关键避坑点
- 绝对不能把服务账号密钥放前端:一旦暴露,任何人都能随便改你的表格,密钥要存在后端的环境变量或者加密配置里
- 表格权限要掐死:只给服务账号授权,其他任何人都不能访问表格,包括你的个人邮箱(除非你自己需要手动编辑)
- 前后端都要做格式校验:前端校验给用户即时反馈,后端校验防止恶意数据绕过前端
- 错误处理要贴心:捕获API的各种错误,比如表格不存在、权限不够、数据格式错,返回用户能看懂的提示
内容的提问来源于stack exchange,提问作者OverwatchUnit3179
相关产品推荐
相关产品推荐

