Flutter集成Google Calendar API时遇请求无效的访问拦截问题
Google日历事件创建URL跳转报错:请求无效问题排查与修复
访问被拦截:project-Client_ID请求无效,您无法登录,因为project-Client_ID发送了无效请求。您可以稍后重试,或联系开发者解决此问题。
我们已尝试创建Event对象并添加至Google日历,使用的依赖库:
- googleapis: ^11.3.0
- googleapis_auth: ^1.4.1
- url_launcher: ^6.1.12
当前实现代码:
class CalendarClient { static const _scopes = [CalendarApi.calendarScope]; insert(title, startTime, endTime) { var _clientID = new ClientId( "Client_ID", ""); clientViaUserConsent(_clientID, _scopes, prompt).then((AuthClient client) { var calendar = CalendarApi(client); calendar.calendarList.list().then((value) => print("VAL________$value")); String calendarId = "primary"; Event event = Event(); // Create object of event event.summary = title; EventDateTime start = new EventDateTime(); start.dateTime = startTime; start.timeZone = "GMT+05:00"; event.start = start; EventDateTime end = new EventDateTime(); end.timeZone = "GMT+05:00"; end.dateTime = endTime; event.end = end; try { calendar.events.insert(event, calendarId).then((value) { print("ADDEDDD_________________${value.status}"); if (value.status == "confirmed") { log('Event added in google calendar'); } else { log("Unable to add event in google calendar"); } }); } catch (e) { log('Error creating event $e'); } }); } void prompt(String url) async { print("Please go to the following URL and grant access:"); print(" => $url,, Start Time >> "); print(""); if (await canLaunchUrl(Uri.parse(url))) { await launchUrl(Uri.parse(url)); } else { throw 'Could not launch $url'; } } }
常见原因及修复方案
1. Client ID配置错误
- 确认
ClientId传入的是Google Cloud Console生成的OAuth 2.0客户端ID,而非项目ID。 - 匹配客户端ID类型:移动端应用需创建对应平台(Android/iOS)的客户端ID,不能用Web应用类型ID。
- 配置正确的重定向URI:在Google Cloud Console的OAuth客户端设置中,添加对应平台的重定向URI(如Android的
com.your.app:/oauth2redirect,iOS的com.your.app://oauth2callback)。
2. OAuth同意屏幕与权限配置
- 在Google Cloud Console的OAuth同意屏幕中,添加
calendar.events相关权限;测试阶段需添加测试用户,否则未发布应用无法授权。 - 可使用更窄的权限范围:如果仅需创建事件,替换
_scopes为[CalendarApi.calendarEventsScope],减少权限申请范围。
3. 代码逻辑优化
改用async/await替代嵌套then,提升可读性与错误处理能力,并优化授权跳转模式:
class CalendarClient { static const _scopes = [CalendarApi.calendarScope]; Future<void> insert(String title, DateTime startTime, DateTime endTime) async { final _clientID = ClientId("YOUR_VALID_CLIENT_ID", ""); try { final AuthClient client = await clientViaUserConsent(_clientID, _scopes, prompt); final calendar = CalendarApi(client); // 验证客户端连接状态 final calendarList = await calendar.calendarList.list(); print("CALENDAR LIST: $calendarList"); final String calendarId = "primary"; final Event event = Event() ..summary = title ..start = EventDateTime() ..dateTime = startTime ..timeZone = "GMT+05:00" ..end = EventDateTime() ..dateTime = endTime ..timeZone = "GMT+05:00"; final insertedEvent = await calendar.events.insert(event, calendarId); print("EVENT STATUS: ${insertedEvent.status}"); if (insertedEvent.status == "confirmed") { print('事件已添加至Google日历'); } else { print('无法添加事件至Google日历'); } } catch (e) { print('创建事件出错: $e'); } } Future<void> prompt(String url) async { print("请访问以下URL并授权:"); print(" => $url"); if (await canLaunchUrl(Uri.parse(url))) { // 使用外部浏览器打开授权页面,避免WebView兼容性问题 await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication); } else { throw '无法打开URL: $url'; } } }
4. 其他排查点
- 确保设备时间与网络时间同步,时间偏差会导致OAuth请求失效。
- 清除应用缓存,并在Google账号设置的「第三方应用访问」中移除该应用的授权记录,重新授权测试。
内容的提问来源于stack exchange,提问作者jeel
相关产品推荐
相关产品推荐

