Google Photos授权错误400:invalid_request排查求助
解决Google Photos上传Error 400: invalid_request问题
以下是针对你遇到的问题的具体排查和解决方案:
1. 确认OAuth客户端ID类型匹配
如果你开发的是Flutter移动端应用,必须创建Android/iOS专属的OAuth客户端ID,不能使用Web应用或其他类型的客户端ID。
- 登录Google Cloud Console,进入项目的「OAuth 2.0客户端ID」列表,检查对应平台的客户端ID是否存在;
- 确保Android客户端的包名与
AndroidManifest.xml中的package属性完全一致,iOS客户端的Bundle ID与Info.plist的CFBundleIdentifier完全匹配。
2. 修正OAuth同意屏幕配置
- 确保你在OAuth同意屏幕中添加了
https://www.googleapis.com/auth/photoslibrary(或photoslibrary.append)权限范围,且状态为已保存; - 如果应用处于测试状态,必须在「测试用户」列表中添加你用来登录的Google账号,未添加测试用户的情况下,非发布应用会直接触发无效请求;
- 若应用已发布,确认权限范围已通过Google审核(测试阶段无需发布,仅需配置测试用户)。
3. 修复上传请求的细节问题
3.1 动态匹配文件MIME类型
你代码中硬编码了X-Goog-Upload-Content-Type: image/png,如果上传的是JPG或其他格式图片,会导致请求无效。可以通过mime包动态获取文件类型:
// 先在pubspec.yaml添加依赖:mime: ^1.0.4 import 'package:mime/mime.dart'; // 修改upload方法中的headers部分 var mimeType = lookupMimeType(file.path) ?? 'image/jpeg'; var tokenResult = await client.post( Uri.parse('https://photoslibrary.googleapis.com/v1/uploads'), headers: { 'Content-type': 'application/octet-stream', 'X-Goog-Upload-Content-Type': mimeType, 'X-Goog-Upload-Protocol': 'raw' }, body: file.readAsBytesSync(), );
3.2 清理上传Token
上传接口返回的token可能包含多余空白字符,需要trim后再使用:
var uploadToken = tokenResult.body.trim(); // 在batchCreate请求中替换原token "uploadToken": uploadToken,
4. 完善错误捕获定位问题
你当前的错误处理仅打印e,无法获取具体错误详情,修改getHttpClient方法捕获完整错误信息:
Future<AuthClient> getHttpClient() async { try { AuthClient authClient = await clientViaUserConsent( ClientId(clientId), _scopes, _userPrompt ); return authClient; } catch (e) { print('认证错误详情: $e'); rethrow; } }
通过打印的详细错误,可直接定位是invalid_client、invalid_scope还是其他具体原因。
5. 验证SHA哈希值与包名一致性
- Android端:确认Google Cloud中配置的SHA1/SHA256是你当前使用的签名证书哈希(调试证书和发布证书哈希不同,不要混用);
- 核对包名是否与应用配置完全一致,包括大小写和特殊字符。
6. 调整权限范围(可选)
如果仅需要上传图片权限,使用更严格的photoslibrary.append范围即可,更容易通过审核且减少权限风险:
final List<String> _scopes = [ 'https://www.googleapis.com/auth/photoslibrary.append' ];
修改后记得同步更新OAuth同意屏幕中的权限范围。
内容的提问来源于stack exchange,提问作者ahmed wael
相关产品推荐
相关产品推荐

