Как совершать последующие аутентифицированные звонки в Google API с помощью Passport.js - PullRequest
0 голосов
/ 27 сентября 2019

Я пытаюсь аутентифицировать и авторизовать пользователей с помощью Passport.js с помощью Google API.У меня есть G Suite, и все мои пользователи являются частью организации G Suite.Я настроил кучу ролей в G Suite для использования с моим пользовательским приложением.

Аутентификационная часть в порядке и работает, как задумано.Проблема в том, что мне нужно сделать последующий вызов https://www.googleapis.com/admin/directory/v1/customer/customer/roleassignments с userKey вошедшего в систему пользователя, чтобы получить все настройки, которые есть у этого пользователя, и я не уверен, каков наилучший способ сделать это.

Вот так выглядят соответствующие части моего /login маршрута:

passport.use(
  new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: process.env.BASE_URL + '/login/google/callback'
  },
  function (accessToken, refreshToken, profile, done) {
    return done(null, profile)
  })
)

router.get('/', function (req, res, next) {
  // Render the login button
})

router.get('/google',
  passport.authenticate('google', {
    scope: [
      'email',
      'https://www.googleapis.com/auth/userinfo.profile',
      'https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly'
    ]
  })
)

router.get('/google/callback', function (req, res, next) {
  passport.authenticate('google', function (err, user, info) {
    if (err) { return next(err) }
    if (!user) { return res.redirect('/login?error=no_user') }

    req.login(user, function (err) {
      if (err) { return next(err) }

      const accessToken = req.user.accessToken
      // Maybe do something here?

      return res.redirect('/')
    })
  })(req, res, next)
})

Я могу сохранить accessToken в сеансе пользователя, когда получу его, и просто сделать обратный вызовиспользование токена в качестве токена на предъявителя, и это, вероятно, работает нормально, но так ли это на самом деле?Предоставляет ли Passport.js какой-то механизм, облегчающий последующие аутентифицированные вызовы?

1 Ответ

0 голосов
/ 30 сентября 2019

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

Итак, чтобы настроить пользовательские роли пользователя, настроенные в G Suite Admin, вам нужноможно сделать это, используя внешнюю библиотеку request:

import request from 'request'

passport.use(
  new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: process.env.BASE_URL + '/login/google/callback'
  },
  function (accessToken, refreshToken, profile, done) {
    const url = 'https://www.googleapis.com/admin/directory/v1/customer/' +
      process.env.GOOGLE_CUSTOMER_ID +
      '/roleassignments' +
      '?userKey=' +
      profile.id

    request.get(url, {
      auth: {
        bearer: accessToken
      }
    }, (error, response, body) => {
      if (error) {
        console.error(error)
        return done(null, false, { message: 'Could not authenticate.' })
      }
      const items = JSON.parse(response.body).items
      let role = null
      const roles = items.map((value) => {
        return value.roleId
      })

      if (roles.includes(process.env.GOOGLE_ROLE_ID_ADMIN)) {
        role = 'ADMIN'
      } else if (roles.includes(process.env.GOOGLE_ROLE_ID_OTHER)) {
        role = 'OTHER'
      } else {
        return done(null, false, { message: 'No valid user role' })
      }

      console.log('User role is ' + role)
      profile.role = role
      return done(null, profile)
    })
  })
)

Если вы назначите приобретенную роль для profile, вы можете легко получить к ней доступ позже с помощью req.user.role.

...