Обратный вызов API Google на сервере REST без сохранения состояния

Мы используем типичную настройку MEAN — Angular для рендеринга внешнего интерфейса, node.js (экспресс) в качестве сервера. Статические ресурсы HTML/Javascript обслуживаются с узла без аутентификации. Все данные, отображаемые во внешнем интерфейсе, запрашиваются Angular из node. Angular авторизует пользователя в конечных точках узла, предоставляя JWT-токен носителя в заголовке «Авторизация» запросов ajax.

Это отлично работает, но я в тупике, когда дело доходит до интеграции Google API OAuth2 в этой настройке. Цель состоит в том, чтобы отобразить данные календаря пользователя в веб-приложении:

  1. Angular запрашивает /api/calendars от узла, предоставляющего токен носителя в заголовке запроса.
  2. Если у сервера нет токена доступа Google для этого пользователя, он создает URL-адрес запроса токена Google (включая callbackUrl /api/calendars/googleCallback ) и отправляет его обратно в Angular.
  3. Когда Angular получает в качестве ответа tokenRequest-Url вместо данных календаря, он перенаправляет пользователя на этот URL-адрес, где он вручную предоставляет разрешение веб-приложения.
  4. Google перенаправляет на callback-url с кодом доступа.

Проблема заключается в шаге 4. Поскольку сервер узла не имеет состояния, а перенаправление с Google на /api/calendars/googleCallback?code=XYZ не содержит заголовка авторизации, сервер не может идентифицировать, не говоря уже об аутентификации пользователя. предоставленный код доступа принадлежит.

Динамическое добавление какого-либо хэша, идентифицирующего пользователя, к URL-адресу обратного вызова не работает (и в любом случае кажется довольно небезопасным), поскольку Google принимает только предварительно указанные фиксированные URL-адреса обратного вызова. Я мог бы сохранить идентификацию пользователя в файле cookie, но это похоже на нарушение общего подхода JWT.

Вопрос может заключаться в том, является ли описанный выше поток в целом плохой идеей или существуют лучшие практики для решения этой ситуации, позволяющие серверной части определить, какому пользователю принадлежит запрос на обратный вызов.

Спасибо!


person Hinnerk    schedule 14.11.2014    source источник


Ответы (1)


Хорошо - упустил из виду простое решение:

Используйте параметр state в запросе токена, который Google направляет и добавляет к callbackurl: 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);
person Hinnerk    schedule 14.11.2014