如何将新访问令牌的刷新令牌发送到Microsoft Graph(Passport-Azure-AD OIDCStrategy)

时间:2018-11-14 21:31:27

标签: node.js azure-active-directory passport.js microsoft-graph

我在理解如何发送刷新令牌以获取新的访问令牌方面遇到困难。

我看过以下文档: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'
    ]

    }, 
    };

0 个答案:

没有答案