question

ian-2771 avatar image
0 Votes"
ian-2771 asked ZehuiYaoMSFT-7151 commented

Msgraph Client request hangs or returns 401 error after obtianing token and send request

I'm trying to make a basic authentication flow that logs the user in and make an http request to the Microsoft Graph API. I have obtained the token from the MSAL library helper functions, and granted the right permissions for my application on admin console in Azure Active Directory, but I always see the 401 error "missing valid authentication token" upon making an http request to the graph API, like "/me/onenote/notebook"

Here's my code:

 const express = require("express");
 const msal = require('@azure/msal-node');
 const graph = require('@microsoft/microsoft-graph-client');
 require('isomorphic-fetch');
 require('dotenv').config();
    
 const session = require('express-session')
    
 const SERVER_PORT = process.env.PORT || 3000;
 const REDIRECT_URI = process.env.OAUTH_REDIRECT_URI;
    
 // Create Express App and Routes
 const app = express();
    
 app.use(session({
     secret:'sec-key',
     resave: false,
     saveUninitialized: false,
     unset: 'destroy'
 }));
    
 // Before running the sample, you will need to replace the values in the config, 
 // including the clientSecret
 const config = {
     auth: {
         clientId: process.env.OAUTH_CLIENT_ID,
         authority: process.env.OAUTH_AUTHORITY,
         clientSecret: process.env.OAUTH_CLIENT_SECRET
     },
     system: {
         loggerOptions: {
             loggerCallback(loglevel, message, containsPii) {
                 console.log(message);
             },
             piiLoggingEnabled: false,
             logLevel: msal.LogLevel.Verbose,
         }
     }
 };
    
 // Create msal application object
 const pca = new msal.ConfidentialClientApplication(config);
 //store msalClient in expressjs in-memory cache for global use
 app.locals.msalClient = pca;
    
 app.get('/', (req, res) => {
     const authCodeUrlParameters = {
         scopes: process.env.OAUTH_SCOPES.split(','),
         redirectUri: REDIRECT_URI,
     };
    
     // get url to sign user in and consent to scopes needed for application
     pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
         res.redirect(response);
     }).catch((error) => console.log(JSON.stringify(error)));
 });
    
 function getAuthenticatedClient(msalClient, userId) {
   if (!msalClient || !userId) {
     throw new Error(
       `Invalid MSAL state. Client: ${msalClient ? 'present' : 'missing'}, User ID: ${userId ? 'present' : 'missing'}`);
   }
    
   // Initialize Graph client
   const client = graph.Client.init({
     // Implement an auth provider that gets a token
     // from the app's MSAL instance
     authProvider: async (done) => {
       try {
         // Get the user's account
         const account = await msalClient
           .getTokenCache()
           .getAccountByHomeId(userId);
    
         if (account) {
           // Attempt to get the token silently
           // This method uses the token cache and
           // refreshes expired tokens as needed
           const response = await msalClient.acquireTokenSilent({
             scopes: process.env.OAUTH_SCOPES.split(','),
             redirectUri: process.env.OAUTH_REDIRECT_URI,
             account: account
           });
    
           // First param to callback is the error,
           // Set to null in success case
           done(null, response.accessToken);
         }
       } catch (err) {
         console.log(JSON.stringify(err, Object.getOwnPropertyNames(err)));
         done(err, null);
       }
     }
   });
    
   return client;
 }
    
 //working OK, got the auth token from the ?code param and saved in memory session
 app.get('/auth/callback', (req, res) => {
     const tokenRequest = {
         code: req.query.code,
         //TODO: look into one note scopes for every function init
         scopes: process.env.OAUTH_SCOPES.split(','),
         redirectUri: REDIRECT_URI,
     };
    
     pca.acquireTokenByCode(tokenRequest).then((response) => {
         req.session.token = response;
         console.log(req.session.token);
         req.session.userId = response.account.homeAccountId;
         console.log(req.session.userId);
         res.sendStatus(200);
     }).catch((error) => {
         console.log(error);
         res.status(500).send(error);
     });
 });
    
 // having isues with 401 error, or code -1 unauthorized permission or missing auth token,. Prob a user permission thing on Azure AD or scope in .env or sth
 app.get('/onenote',(req,res)=>{
   const apiTok = getAuthenticatedClient(pca, req.session.userId)
     .api('/me/onenote/notebooks')
     .get()
     .catch((err)=> console.error(err));
   console.log(apiTok);
 })
    
 app.get('/signout',(req,res)=>{
   req.session.destroy((info)=> console.log('signed out', info))
 })
    
 app.listen(SERVER_PORT, () => console.log(`Msal Node Auth Code Sample app listening on http://localhost:${SERVER_PORT}`))
microsoft-graph-authenticationmicrosoft-graph-notes
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello @ian-2771, have you tried using postman to acquire the token and request the endpoint?

0 Votes 0 ·

Hi @ian-2771, would you mind providing an update on the status of this issue?

0 Votes 0 ·
ian-2771 avatar image ian-2771 ZehuiYaoMSFT-7151 ·

Hi, I will try a plain postman request and see if it works. The MS Graph playground does show my data in One Note though

0 Votes 0 ·
Show more comments

0 Answers