>背景:这是我的第一个独立的Web开发项目,我在Meteor中的唯一经验是在去年夏天构建Discover Meteor应用程序。我有大约一年的CS经验,作为学校的副业,我对C和C++最满意。我有python和java的经验。
到目前为止的项目:我正在创建一个日历管理系统(为了好玩)。使用帐户-谷歌,我创建了通过谷歌进行身份验证的用户帐户。我已请求应用所需的必要权限,包括"身份"和"日历读/写访问权限"。在过去的一周左右的时间里,我一直在试图克服下一个障碍,实际上是从谷歌获取数据。
目标:我希望能够使用 GET 请求对 Calendar.list 进行 API 调用。我已经调用meteor add http
来添加GET请求功能,我的问题来自实际实现。
问题:我已经在开发者控制台上注册了我的应用,并使用客户端 ID 和密钥设置了帐户,但无法找到/生成用于请求的"API 密钥"。这是使用我(已经)下载的私钥创建访问令牌的谷歌指南。我很难使用 JS 在服务器端进行实现,因为我对实现示例的 HTTP/REST 部分中提到的内容没有太多经验。我将不胜感激有关如何实现握手和接收访问令牌以在我的应用程序中使用的一些帮助。如果我可以进行调用或一些包来处理我的令牌生成,那将比实现帮助更好。我相信这个问题的答案也会有利于另一个问题
到目前为止,我一直在参考的SO答案:https://stackoverflow.com/a/14543159/4259653 其中一些是西班牙语,但它是很容易理解的代码。他有一个用于请求的 API 密钥,我问这个问题是为了帮助我。accounts-google
文档并不足以向我解释这一切。
还有一个不相关的小问题:处理请求中的"时间"参数的最简单方法是什么。我假设JS具有某种我还不知道的内置功能。
感谢您的研究。我也问了一个非常相似的问题,现在我正在研究你推荐的软件包。我考虑过这个流星-谷歌-api包,但它看起来被遗弃了。
关于你关于时间操纵的问题,我推荐MomentJS。那里有很多软件包;我正在使用meteor add mrt:moment
编辑:MomentJS现在有一个官方的Meteor软件包,所以使用meteor add momentjs:moment
而不是上面的mrt
命令
以下是时刻可以做什么的片段。更多文档在这里。
var startTimeUTC = moment.utc(event.startTime, "YYYY-MM-DD HH:mm:ss").format();
//Changes above formatting to "2014-09-08T08:02:17-05:00" (ISO 8601)
//which is acceptable time format for Google API
所以我开始尝试在服务器端自己实现所有这些,但对我正在做的许多硬编码和我为填补空白而做出的假设持谨慎态度。我的安全教授曾经说过"永远不要自己实现加密",所以我决定再找一个有用的软件包。将搜索条件修改为"JWT",我找到了Jagi在大气层上的meteor-google-oauth-jwt
。自述文件很全面,提供了我需要的一切。按照 Google OAuth 指南中使用的流程,可以发出授权请求并生成用于进行 API 调用的密钥。
链接到大气:https://atmospherejs.com/jagi/google-oauth-jwt
链接到回购:https://github.com/jagi/meteor-google-oauth-jwt/
我将用我在 Google API 过程中遇到的任何其他障碍以及我如何解决它们来更新这个答案:
最近,我遇到了 API 请求结果的问题。我从 API 调用中返回一个空日历列表。我怀疑这是因为我对我的开发人员帐户而不是主题用户进行了 API 调用。我将调查该问题,然后创建一个新问题或使用我找到的修复程序更新此解决方案。
修复:未将"子"限定符包含在 JWT 令牌中。通过修改 JWT 包令牌生成代码以在 scope
之后包含delegationEmail: user.services.google.email
来修复。我不知道为什么他对选项使用了这么长的名称,而不是像谷歌 API 中那样sub:
,但我非常感谢他的软件包。
我很快就精通了这一点,所以如果人们有与流星相关的谷歌身份验证问题,请告诉我。
不要使用上面发布的服务帐户!
正确的方法是使用标准 Web 访问 + 请求脱机访问。api 页面上的文档特别指出了这一点:
通常,当应用使用 Google API 处理自己的数据而不是用户的数据时,应用会使用服务帐号。
唯一的例外情况是,当您使用 Google Apps 网域帐号并希望为整个网域委派对您的服务帐号的访问权限时:
授权服务帐号代表网域中的用户访问数据有时称为"委派网域范围的权限"
这在逻辑上是有意义的,因为必须允许用户"授权"您的应用程序。
回到海报原题流程很简单:
1)流星帐户谷歌包已经为你完成了大部分工作来获取代币。您可以包括所需的脱机访问范围。
2) 如果您正在构建自己的流程,您将按照身份验证上的说明完成库存标准流程和调用
这将要求您:
1)HTTP调用来发出原始请求,或者你可以搭载一些内部的流星调用:Package.oauth.OAuth.showPopup() - 去看看源代码,那里有更多漂亮的功能。
2) 然后,您需要创建一个 Iron 路由器服务器端路由来接受 oauth 响应,该响应将包含一个代码参数,您将使用该参数来交换令牌。
3)接下来使用此代码进行最终调用,将"代码"交换为令牌+refresh_token
4)将它们存储在您想要的任何位置 - 我的要求不是将它们存储在用户级别,而是每个用户多个
5)使用像GoogleAPI这样的包,它会包装Google API调用并在需要时刷新 - 它仅在令牌存储在用户帐户中时才有效,因此如果您的令牌存储在其他地方(就像我的情况一样),则需要将其拆开一点