MSAL does not return the new token after an acquireSilent()
See original GitHub issueI’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:
Browser:
- Chromium version 74 (with Brave)
- Firefox version XX
- IE version XX
- Edge version XX
- Safari version XX
Library version
Library version: 1.0.1
Current behavior
- I’m using MSAL with VueJS
- I use the localStorage (and not the sessionStorage)
- I use axios to intercept outgoing requests to my API, and inject the
accessToken
fromacquireTokenSilent()
as a bearer token
When the token expires, MSAL fetches a new one (using acquireTokenSilent()
), updates the localStorage accordingly, but still returns the old one. As a result, when I call my API, I have 401 errors.
- When I refresh the page,
acquireTokenSilent()
returns the new token. - When I open a new tab from the same app, the new tab
acquireTokenSilent()
returns the new token. However, the old tab still uses the old token
The localStorage just after a login:
After a token refresh:
The new token is present (in green), while the old one is still there in red. MSAL still returns the old one when calling acquireTokenSilent()
Expected behavior
MSAL should use the new token
Minimal reproduction of the problem with instructions
The ajax interceptor:
axios.interceptors.request.use(
async request => {
await setToken(request)
return request
},
error => {
return Promise.reject(error)
}
)
const setToken = async (request: any) => {
const res = await authService.getAuthResponse() as Msal.AuthResponse
request.headers.common['Authorization'] = `Bearer ${res.accessToken}` // This fails if MSAL requested a new token
}
The authService:
public async getAuthResponse(): Promise<null | Msal.AuthResponse> {
const tokenRequest = {
scopes: this.graphScopes
}
try {
return await this.userAgentApp.acquireTokenSilent(tokenRequest)
}
catch (e) {
this.userAgentApp.acquireTokenRedirect(tokenRequest)
return null
}
}
UPDATED WORKAROUND:
To manually retrieve the correct token:
function extractMSALToken() {
const timestamp = Math.floor((new Date()).getTime() / 1000)
let token = null
for (const key of Object.keys(localStorage)) {
if (key.includes('"authority":')) {
const val: any = JSON.parse(localStorage.getItem(key)!)
if (val.expiresIn) {
// We have a (possibly expired) token
if (val.expiresIn > timestamp && val.idToken === val.accessToken) {
console.log(key)
// Found the correct token
token = val.idToken
}
else {
console.log('will remove ' + key)
// Clear old data
localStorage.removeItem(key)
}
}
}
}
if (token) return token
throw new Error('No valid token found')
}
Old workaround (invalid):
const setToken = async (request: any) => {
// Make sure that MSAL token is up-to-date
const res = await authService.getAuthResponse() as Msal.AuthResponse
// DIRTY FIX : directly fetch the token from the localStorage
request.headers.common['Authorization'] = `Bearer ${localStorage.getItem('msal.idtoken')}`
// request.headers.common['Authorization'] = `Bearer ${res.accessToken}` // This doesn't work
}
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:33 (16 by maintainers)
Top Results From Across the Web
Not getting token with acquireTokensilent but ... - Stack Overflow
Summarize the comments into the answer in order to archive this question: Giving account object in the request can resolve this issue.
Read more >Single-page application: Acquire a token to call an API
If no access token is found or the access token found has expired, it attempts to use its refresh token to get a...
Read more >Microsoft Authentication Library for JavaScript (MSAL.js)
It also enables your app to get tokens to access Microsoft Cloud services such ... Internet Explorer does not have native Promise support,...
Read more >React Msal Dose Not Return The Web API Custom Scope
The Microsoft identity platform endpoint does not allow you to get a token for ... MSAL does not return the new token after...
Read more >MSAL Python 1.20.0 documentation
This method will combine the cache empty and refresh error into one return value, None . If your app does not care about...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Guys,
This is a severe issue with a Microsoft product. Can we please get an update and an ETA to fix?
Cheers
Updated workaround: getting
msal.idtoken
from the localStorage does not work reliably, as the value is sometimes (often) not correctly updated by msal.This function seems to get the correct, up-to-date token more reliably: