OAuth2 обратный вызов - определить пользователя? - PullRequest
1 голос
/ 28 апреля 2019

Я работаю над веб-приложением, в котором мне нужно попросить пользователя предоставить доступ к его календарю Google (чтобы я мог читать и создавать события от его имени).

Чтобы подвести итог моего вопроса, рассмотрим поток oauth:

клиент (сеанс) -> бэкэнд (сеанс) -> google (предоставление доступа) -> бэкэнд (как сделать Я знаю пользователя на этом шаге для сохранения refresh_token?)

Возможное фиктивное решение:

клиент (сеанс) -> бэкэнд (сеанс) -> google (предоставление доступа) -> клиент (сеанс) -> бэкэнд (сеанс)

Подробнее

Вот поток по умолчанию:

  • пользователь входит в мое веб-приложение ( клиент )
  • веб-приложение затем просит пользователя запустить поток oauth2 ( клиент )
  • , поэтому пользователь нажимает кнопку «Запустить поток авторизации», которая отправляет запрос «Запустить поток авторизации» в мой бэкэнд ( клиент )
  • на сервере есть oauth-клиент, который генерирует URL-адрес запроса и перенаправляет пользователя на этот URL-адрес ( backend ):
const authUrl = new google.auth.OAuth2(clientId, secret, redirectUrl)).generateAuthUrl(options)
res.redirect(authUrl)
  • перенаправляет пользователя на страницу согласия Google. ( Google )
  • Как только пользователь получил разрешение, он перенаправляется обратно на URL, указанный в клиенте OAuth2 ( backend , моя конечная точка "обратного вызова")
  • на данный момент мне нужно сохранить refresh_token в расположении базы данных пользователя. ( бэкенд )

И вот вопрос: как я понимаю в «обратном вызове», что это все тот же пользователь, который запустил поток?

Это может звучать глупо, но я застрял с этим.

Я понимаю, что сессия должна решить эту проблему, но, поскольку "обратный вызов" запускается сервером Google и является моей конечной точкой бэкэнда (а не страницей браузера), сеанса не будет, если я что-то упустил.

В моем понимании, это то, как это может быть реализовано, что сначала включает перенаправление в браузер:

  • пользователь входит в мое веб-приложение, и я устанавливаю cookie сеанса ( клиент )
  • пользователь запускает поток oauth2 ( клиент / серверная часть )
  • обратный вызов затем перенаправляет обратно на некоторую фиктивную страницу на стороне клиента ( google )
  • эта фиктивная страница извлекает код авторизации, переданный из Google, и отправляет его в мою конечную точку бэкэнда, пропуская сеанс по пути ( клиент )
  • теперь сервер знает, кто выполнил «обратный вызов» ( backend )

Но это не похоже на хороший подход со всем этим между клиентом и бэкэндом

Так есть ли способ идентифицировать пользователя во время обратного вызова, не задействуя браузер в середине процесса? Как это сделать?

Я работаю с nodejs и выражаю в случае, если это имеет значение

Спасибо

Ответы [ 3 ]

0 голосов
/ 16 мая 2019

Попробуйте использовать passportJs , который обеспечивает аутентификацию с использованием сторонних поставщиков аутентификации.

var GoogleStrategy = require( 'passport-google-oauth2' ).Strategy;

passport.use(new GoogleStrategy({
    clientID:     GOOGLE_CLIENT_ID,
    clientSecret: GOOGLE_CLIENT_SECRET,
    callbackURL: "http://yourdormain:3000/auth/google/callback",
    passReqToCallback   : true   },   function(request, accessToken, refreshToken, profile, done) {
    User.findOrCreate({ googleId: profile.id }, function (err, user) {
      return done(err, user);
    });   } ));
0 голосов
/ 17 мая 2019

Оказалось, что есть параметр с именем state, который можно использовать для передачи определенных данных, и Google вернет их обратно. Это решает мой вопрос, поскольку я могу передать идентификатор пользователя или токен сеанса как состояние и прочитать его в обратном вызове.

Из документа :

состояние Рекомендуется.

Указывает любое строковое значение, которое ваше приложение использует для поддержания состояния между вашим запросом авторизации и ответ сервера авторизации. Сервер возвращает точное значение который вы отправляете в виде пары имя = значение во фрагменте хеша (#) redirect_uri после того, как пользователь согласится или отклонит ваше приложение запрос доступа.

В случае nodejs google oauth2 библиотека может выглядеть так:

oauth2ClientGlobal.generateAuthUrl({
            access_type: 'offline',
            scope: this.scopes(),
            state: base64UserId // <- google will return this param back
        });
0 голосов
/ 29 апреля 2019

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

Создайте идентификатор для пользователя, используйте этот идентификатор для сопоставления с данными клиента на сервере, такими как токен обновления. Передайте этот идентификатор обратно браузеру и клиенту в файлах cookie или JWT. Затем, когда пользователь отправляет запрос обратно на ваш сервер, он всегда передает тот идентификатор, который вы создали в куки. Этот идентификатор можно использовать для поиска пользователя в базе данных и получения токена обновления.

...