无状态 REST 服务器上的 Google API 回调

Posted

技术标签:

【中文标题】无状态 REST 服务器上的 Google API 回调【英文标题】:Google API Callback on Stateless REST server 【发布时间】:2015-01-11 23:22:06 【问题描述】:

我们正在运行一个典型的 MEAN 设置 - Angular 用于前端渲染,node.js (express) 作为服务器。 静态 html/javascript 资产从节点提供,无需身份验证。 前端显示的所有数据都是 Angular 从节点请求的。 Angular 通过在 ajax 请求的“Authorization”标头中提供不记名 JWT 令牌来针对节点端点授权用户。

这很好用,但是当涉及到此设置中的 Google API OAuth2 集成时,我处于死胡同。 目标是在 webapp 中显示用户的日历数据:

    Angular 请求 /api/calendars 从在请求标头中提供不记名令牌的节点。 如果服务器还没有该用户的 Google 访问令牌,它会创建一个 Google 令牌请求 URL(包括 callbackUrl /api/calendars/googleCallback )并将其发送回 Angular。 当 Angular 收到一个 tokenRequest-Url 作为响应而不是日历数据时,它会将用户重定向到这个 URL,他在该 URL 中手动授予 webapp 权限。 Google 重定向到提供访问代码的回调 URL。

问题是第 4 步 - 因为节点服务器是无状态的,并且从 Google 到 /api/calendars/googleCallback?code=XYZ 的重定向不包含服务器无法识别的授权标头,更不用说验证提供的访问代码所属的用户。

在回调 URL 中动态添加某种标识用户的哈希是行不通的(而且似乎很不安全),因为 Google 只接受预先指定的固定回调 URL。 我可以将用户标识存储在 cookie 中,但这感觉违反了整个 JWT 方法。

问题是,如果上述流程通常是一个坏主意,或者是否有处理这种情况的最佳做法,以便后端识别回调请求属于哪个用户。

谢谢!

【问题讨论】:

【参考方案1】:

好吧 - 忽略了简单的解决方案:

在令牌查询中使用 state 参数,Google 会通过该参数路由并附加到回调 URL:https://developers.google.com/accounts/docs/OAuth2Login#state-param

在节点中:

var googleApi = require('googleapis');
var oauth2Client = new googleApi.auth.OAuth2(config.clientId, config.clientSecret, config.callbackUrl);

var options = 
    access_type: 'offline',
    state: 'hashed-useridentified',
    scope: [
        'https://www.googleapis.com/auth/calendar.readonly'
    ].join(' ')
;
oauth2Client.redirectUri_ = 'http://someserver.com/api/auth/google/calendar/callback';
var generatedUrl = oauth2Client.generateAuthUrl(options);

【讨论】:

以上是关于无状态 REST 服务器上的 Google API 回调的主要内容,如果未能解决你的问题,请参考以下文章

使用 REST API 向 Google Cloud Platform 上的服务帐户添加角色

Xamarin 上的 Bing Speech API/语音服务(无 REST,sdk websocket 来处理连续识别)

POST / PUT 上的 Java Spring REST API 状态 400 响应

REST 风格的api

Spring Rest api 和 Spring 基本安全

iOS的REST服务-备