JS调用Google Drive API报insufficientFilePermissions错误
问题背景
- 目标:通过JavaScript使用机器对机器认证方式拉取Google Drive中的图片文件列表
- 已完成前置操作:
- 在Google控制台创建对应Google项目
- 为项目激活Google Drive API
- 创建API key与client id
- 现有实现代码:
const API_KEY = '...'; const ID_CLIENT = '...'; const scopes = [ 'https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive.readonly', 'https://www.googleapis.com/auth/drive.activity', 'https://www.googleapis.com/auth/drive.activity.readonly', 'https://www.googleapis.com/auth/drive.metadata', 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/drive.scripts', 'Google_Service_Drive::DRIVE' ]; const googleDriveConf = { 'apiKey': API_KEY, 'clientId': ID_CLIENT, 'scope': scopes[1], 'plugin_name': 'Client Web deca' }; function start() { // Initialize the JavaScript client library and auth. gapi.client.init(googleDriveConf) .then(function () { // Initialize and make the API request. const req = gapi.client.request({ 'path': `https://content.googleapis.com/drive/v3/files`, 'method': 'GET', 'params': { 'q': 'mimeType = "image/jpeg"', } }) console.log(req) return req; }, function (reason) { console.log('auth: ', reason) }) .then(function (response) { console.log(response.result); }, function (reason) { console.log('fetch files: ', reason) //error source }); } gapi.load('client', start);
- 运行报错信息:
{ "error": { "errors": [ { "domain": "global", "reason": "insufficientFilePermissions", "message": "The user does not have sufficient permissions for this file." } ], "code": 403, "message": "The user does not have sufficient permissions for this file." } }
错误码403,提示insufficientFilePermissions,即用户对文件无足够访问权限。
问题根因
- Scope配置错误
当前代码使用的是scopes[1]也就是https://www.googleapis.com/auth/drive.file权限,该权限仅允许访问当前应用自身创建、或者用户主动通过该应用打开过的文件,无法遍历读取Drive中所有jpeg格式图片。另外scopes数组最后一项Google_Service_Drive::DRIVE是PHP客户端的常量写法,在JavaScript环境中完全无效。 - 授权流程缺失
代码仅完成了gapi客户端初始化,既没有加载auth2授权模块,也没有触发OAuth授权登录流程,没有拿到用户授权的有效访问凭证就发起接口请求,自然会被判定权限不足。 - 认证模式与场景不匹配
需求是「机器对机器认证」,但当前写的前端JS gapi客户端是面向前端用户交互的OAuth授权流程,并非无用户参与的M2M服务账号认证;且API key仅能访问公开资源,无法读取用户私有Drive文件。
修复方案
- 如果是前端需要用户登录后拉取自己的Drive图片:
- 替换权限scope为
https://www.googleapis.com/auth/drive.readonly,该权限足够读取所有图片文件,不需要申请多余的高风险权限,同时删除scopes数组中无效的PHP常量项。 - 补全授权检测、登录流程,确保拿到用户有效授权后再发起文件请求,修正后的核心代码参考:
- 替换权限scope为
const API_KEY = '...'; const ID_CLIENT = '...'; // 仅保留需要的scope const SCOPE = 'https://www.googleapis.com/auth/drive.readonly'; const googleDriveConf = { 'apiKey': API_KEY, 'clientId': ID_CLIENT, 'scope': SCOPE, 'plugin_name': 'Client Web deca' }; async function start() { await gapi.client.init(googleDriveConf); const authInstance = gapi.auth2.getAuthInstance(); // 未授权则触发登录弹窗 if (!authInstance.isSignedIn.get()) { await authInstance.signIn(); } // 授权完成后再请求文件列表 const res = await gapi.client.drive.files.list({ 'q': 'mimeType = "image/jpeg"', 'fields': 'files(id, name)' }); console.log(res.result); } // 加载客户端时同时加载auth2模块 gapi.load('client:auth2', start);
- 如果确实需要无用户参与的机器对机器认证:
- 不能在前端JavaScript中实现,前端环境公开无法安全存储服务账号密钥,必须在后端服务中使用服务账号(Service Account)模式认证。
- 服务账号默认拥有独立的存储空间,需要访问个人账号下的Drive文件时,需要将目标文件/文件夹共享给服务账号的邮箱地址,否则同样会报权限不足错误。
内容的提问来源于stack exchange,提问作者kadiro
相关产品推荐
相关产品推荐

