我在理解如何发送刷新令牌以获取新的访问令牌方面遇到困难。
我看过以下文档:https://developer.microsoft.com/en-us/graph/docs/concepts/nodejs,我基本上需要身份验证用户步骤4的帮助,但似乎没有涉及更多细节。
我尝试使用passport-oauth2-refresh,但是我认为因为我使用的是Azure AD,所以我一直收到错误消息:无法注册:不是OAuth2策略。因此,我决定尝试手动检查有效期。
我能够检索刷新令牌(带有req.user.refreshToken的POST /令牌)以及访问令牌,并将其存储在json中,但是我不知道如何将其发回。
这是我的index.js:
const express = require('express');
const router = express.Router();
const graphHelper = require('../utils/graphHelper.js');
const passport = require('passport');
const request = require('request');
const SERVER = process.env.SERVER;
let user_id = null;
router.get('/', (req, res) => {
if (!req.isAuthenticated()) {
res.render('login');
} else {
renderBotPage(req, res);
}
});
router.get('/login',
passport.authenticate('azuread-openidconnect', {failureRedirect: '/'}),
(req, res) => {
res.redirect('/');
});
router.get('/token',
function (req, res, next) {
passport.authenticate('azuread-openidconnect',
{
response: res, // required
failureRedirect: '/'
}
)
},
function (req, res) {
const options = {
headers: {
'content-type' : 'application/json'
},
method: 'POST',
url: SERVER,
json: {
'accessToken': req.user.accessToken,
'refreshToken': req.user.refreshToken
}
};
request(options,
function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body)
}
}
);
console.log('We received a return from AzureAD get token.');
res.redirect('/');
});
router.post('/token',
function (req, res, next) {
passport.authenticate('azuread-openidconnect',
{
response: res, // required
failureRedirect: '/'
}
)(req, res, next);
},
function (req, res) {
console.log('res after first token function', res);
const options = {
headers: {
'content-type' : 'application/json'
},
method: 'POST',
url: SERVER,
json: {
'accessToken': req.user.accessToken,
'refreshToken': req.user.refreshToken
}
};
request(options,
function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body)
}
}
);
res.redirect('/');
});
function renderBotPage(req, res) {
graphHelper.getUserData(req.user.accessToken, (err, user) => {
if (!err) {
res.render('chatbotOn', {
display_name: user.body.displayName,
user_id:user.body.id
});
} else {
// Catch of Expired token error
if (hasAccessTokenExpired(err)) {
req.session.destroy(() => {
req.logOut();
res.clearCookie('graphNodeCookie');
res.status(200);
res.redirect('/');
});
}
renderError(err, res);
res.render('chatbotOn', {
display_name: "Random User"
});
}
});
}
router.get('/disconnect', (req, res) => {
req.session.destroy(() => {
req.logOut();
res.clearCookie('graphNodeCookie');
res.status(200);
res.redirect('/');
});
});
function hasAccessTokenExpired(e) {
let expired;
if (!e.innerError) {
expired = false;
} else {
expired = e.forbidden &&
e.message === 'InvalidAuthenticationToken' &&
e.response.error.message === "Le token d'accès a expiré.";
}
return expired;
}
function renderError(e, res) {
e.innerError = (e.response) ? e.response.text : '';
res.render('error', {
error: e
});
}
module.exports = router;
我的app.js
const callback = (iss, sub, profile, accessToken, refreshToken, done) => {
done(null, {
profile,
accessToken,
refreshToken
});
};
passport.use(new OIDCStrategy(config.creds, callback));
这是我的graphHelper.js:
const request = require('superagent');
function getUserData(accessToken, callback) {
request
.get('https://graph.microsoft.com/beta/me')
.set('Authorization', 'Bearer ' + accessToken)
.end((err, res) => {
callback(err, res);
});
}
exports.getUserData = getUserData;
这是我的config.js:
module.exports = {
creds: {
redirectUrl: 'http://localhost:3000/token',
clientID: 'xxxxx', // regular
clientSecret: 'xxxxx', // regular
identityMetadata:
'xxxxxx',
allowHttpForRedirectUrl: true, // For development only
responseType: 'code id_token',
validateIssuer: false, // For development only
responseMode: 'form_post',
scope: ['openid', 'offline_access', 'Contacts.Read',
'Calendars.ReadWrite'
]
},
};