Laravel应用调用Google Drive创建文件夹时出现401无效凭证错误
Laravel 接入Google Drive 创建文件夹时401认证错误解决
问题详情
尝试通过Laravel应用在Google Drive创建文件夹,已确认Google Drive凭证正确,但持续收到401错误:
{ "error": { "code": 401, "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project., "errors": [ { "message": "Invalid Credentials", "domain": "global", "reason": "authError", "location": "Authorization", "locationType": "header" } ], "status": "UNAUTHENTICATED" } }
对应的Controller代码:
try { $client = new Client(); $client->setApplicationName('MyAppTest'); $client->setClientId(env('GOOGLE_APP_ID')); $client->setClientSecret(env('GOOGLE_APP_SECRET')); $client->setAccessToken(env('GOOGLE_OAUTH_ACCESS_TOKEN')); // $client->useApplicationDefaultCredentials(); $client->addScope(Drive::DRIVE); $driveService = new Drive($client); $fileMetadata = new Drive\DriveFile(array( 'name' => 'Invoices', 'mimeType' => 'application/vnd.google-apps.folder')); $file = $driveService->files->create($fileMetadata, array( 'fields' => 'id')); printf("Folder ID: %s\n", $file->id); return $file->id; }catch(Exception $e) { echo "Error Message: ".$e; }
排查与解决步骤
1. 验证OAuth2访问令牌有效性
- 确认
GOOGLE_OAUTH_ACCESS_TOKEN是有效的OAuth2访问令牌,而非服务账号密钥或其他类型凭证。手动获取的OAuth2令牌默认有效期仅1小时,过期后会触发401错误。 - 若需长期使用,必须实现令牌自动刷新逻辑:从存储的令牌中取出
refresh_token,调用$client->fetchAccessTokenWithRefreshToken()更新令牌,并将新令牌保存(建议存数据库,而非.env文件)。
2. 确认凭证类型与代码匹配
- 如果使用服务账号认证,需启用
$client->useApplicationDefaultCredentials(),同时注释掉手动设置access token的代码。此外,要在Google控制台启用Drive API,并将目标共享文件夹权限授予服务账号邮箱。 - 如果使用OAuth2授权码模式,必须确保令牌包含
refresh_token,否则无法自动刷新。
3. 检查Scope权限
确认申请令牌时已包含所需的Scope(如Drive::DRIVE),若权限不足也可能导致认证失败。可尝试使用更具体的Scope如Drive::DRIVE_FILE缩小权限范围。
修正后的代码示例
服务账号认证版本
try { $client = new Client(); $client->setApplicationName('MyAppTest'); // 使用服务账号默认凭证 $client->useApplicationDefaultCredentials(); $client->addScope(Drive::DRIVE); $driveService = new Drive($client); $fileMetadata = new Drive\DriveFile([ 'name' => 'Invoices', 'mimeType' => 'application/vnd.google-apps.folder' ]); $file = $driveService->files->create($fileMetadata, [ 'fields' => 'id' ]); printf("Folder ID: %s\n", $file->id); return $file->id; } catch(Exception $e) { echo "Error Message: ".$e; }
OAuth2自动刷新令牌版本
try { $client = new Client(); $client->setApplicationName('MyAppTest'); $client->setClientId(env('GOOGLE_APP_ID')); $client->setClientSecret(env('GOOGLE_APP_SECRET')); // 从.env获取令牌(需包含refresh_token) $accessToken = json_decode(env('GOOGLE_OAUTH_ACCESS_TOKEN'), true); $client->setAccessToken($accessToken); // 令牌过期时自动刷新 if ($client->isAccessTokenExpired()) { $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken()); $newAccessToken = $client->getAccessToken(); // 生产环境建议将新令牌存入数据库,而非直接修改.env // 这里仅作示例,实际需根据存储方案调整 } $client->addScope(Drive::DRIVE); $driveService = new Drive($client); $fileMetadata = new Drive\DriveFile([ 'name' => 'Invoices', 'mimeType' => 'application/vnd.google-apps.folder' ]); $file = $driveService->files->create($fileMetadata, [ 'fields' => 'id' ]); printf("Folder ID: %s\n", $file->id); return $file->id; } catch(Exception $e) { echo "Error Message: ".$e; }
内容的提问来源于stack exchange,提问作者mikasa acker
相关产品推荐
相关产品推荐

