I am working on a project where I need to create events in user's Outlook calendars. The requirement is that job inspection dates should be added to the calendar of relevant users. Additionally, users should have the ability to manually create events on their calendars.
What I have imlemented:
- User will be redirected to microsoft login page.
- After login Microsoft will give us access token for that user.
- Using getTokenCache we are getting refresh token for that user.
Here is the code:
Routes:
router.get('/login', getAuthCodeUrl);
router.get('/callback', handleCallback);
Controllers:
const { ConfidentialClientApplication } = require('@azure/msal-node');
// TEST APP
const clientId = '945bf51b-xxxx-c5a83898b4b8';
const clientSecret = '9mV8Q~xxxx.zf9GqLGt95UUJ_bGdcp';
const msalConfig = {
auth: {
clientId: clientId,
authority: `https://login.microsoftonline.com/common`,
clientSecret: clientSecret,
},
};
const redirectUri = 'http://localhost:3000/api/callback';
const scopes = [
'User.Read',
'Calendars.ReadWrite',
'offline_access',
'openid',
'profile',
];
const cca = new ConfidentialClientApplication(msalConfig);
const getAuthCodeUrl = async (req, res) => {
const authCodeUrlParameters = {
scopes,
redirectUri,
};
const authUrl = await cca.getAuthCodeUrl(authCodeUrlParameters);
console.log('authUrl: ', authUrl);
res.redirect(authUrl);
};
const handleCallback = async (req, res) => {
const tokenRequest = {
scopes,
code: req.query.code,
redirectUri,
accessType: 'offline',
};
try {
const authResult = await cca.acquireTokenByCode(tokenRequest);
const accessToken = authResult.accessToken;
const refreshToken = () => {
const tokenCache = cca.getTokenCache().serialize();
const refreshTokenObject = JSON.parse(tokenCache).RefreshToken;
const refreshToken =
refreshTokenObject[Object.keys(refreshTokenObject)[0]].secret;
return refreshToken;
};
const tokens = {
accessToken,
refreshToken: refreshToken(),
};
console.log('tokens: ', tokens);
// Handle token result, store tokens, etc.
res.send('Authentication successful. You can close this window.');
} catch (error) {
console.error('Error obtaining access token:', error);
res.status(500).send('Error obtaining access token');
}
};
Here are my questions:
- In our refreshToken function, we are not passing any thing related to this user. I am confused how MSAL gets refresh tokens for this user and not any other?
- "access token can only be refreshed for a maximum period of 90 days", I read this on many places while researching. Does user needs to login every 90 days?
- Can we get new refresh token without need of user to login again?
- How do we know if access token is expired or not? Do we need to call profile (or any other) API for to check expiration of access token?
cca.getTokenCache().serialize(), it returns the serialized token cache, which includes the refresh token for the user.Note that: Access token can only be refreshed for a maximum period of 90 days. Refer this MsDoc
expires_inproperty.Reference:
microsoft-authentication-library-for-js/lib/msal-browser/docs/token-lifetimes.md at dev · AzureAD/microsoft-authentication-library-for-js · GitHub