如何使用 Passport.js 对 Google API 进行后续的、经过身份验证的调用
How to make subsequent, authenticated calls to Google API using Passport.js
我正在尝试使用 Google API 对 Passport.js 用户进行身份验证和授权。我有 G Suite,我的所有用户都是 G Suite 组织的一部分。我在 G Suite 中设置了一系列角色以用于我的自定义应用程序。
身份验证部分没有问题并且按预期工作。问题是我需要使用登录用户的 userKey
对 https://www.googleapis.com/admin/directory/v1/customer/customer/roleassignments
进行后续调用,以获取该用户拥有的所有分配,我不确定什么是最好的方法这样做。
这是我的 /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 是否提供某种机制来简化后续的经过身份验证的调用?
经过进一步调查,如果您在初始身份验证后需要执行其他步骤,我认为您应该修改 Strategy 回调。
因此,要在 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
轻松访问它。
我正在尝试使用 Google API 对 Passport.js 用户进行身份验证和授权。我有 G Suite,我的所有用户都是 G Suite 组织的一部分。我在 G Suite 中设置了一系列角色以用于我的自定义应用程序。
身份验证部分没有问题并且按预期工作。问题是我需要使用登录用户的 userKey
对 https://www.googleapis.com/admin/directory/v1/customer/customer/roleassignments
进行后续调用,以获取该用户拥有的所有分配,我不确定什么是最好的方法这样做。
这是我的 /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 是否提供某种机制来简化后续的经过身份验证的调用?
经过进一步调查,如果您在初始身份验证后需要执行其他步骤,我认为您应该修改 Strategy 回调。
因此,要在 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
轻松访问它。