vmurin / react-native-azure-auth

React Native library implementing Azure AD OAuth2 API
MIT License
85 stars 64 forks source link

AcquireTokenSilent error - [TypeError: Cannot read property 'accessToken' of null] #205

Closed Monisankarnath closed 5 months ago

Monisankarnath commented 5 months ago

@vmurin, If I try to login using webAuth.authorize I am able to login by adding the email and password in the b2c login and get the response, after that if I try to login using auth.acquireTokenSilent I get an error - [TypeError: Cannot read property 'accessToken' of null]. Now, if I try webAuth.authorize again I dont need to add email and password and it directly allows me to login after a popup.

Both the getAccessToken and getRefreshToken are returning null. The cache is not getting retained because after we are closing the app and opening it's a new instance. How can we use the old cache?

Package versions -

Originally posted by @Monisankarnath in https://github.com/vmurin/react-native-azure-auth/issues/45#issuecomment-1916561411

Monisankarnath commented 5 months ago

Resolved

vmurin commented 5 months ago

Could you please shortly report about your solution

Monisankarnath commented 5 months ago

sure @vmurin. So the userId we get from the response of authorize and acquireSilent doesnot match with the userId we get in our profile APIs. I was calling acquireSilentToken with our profile api userId. I am guessing the userId from the library is a key that is used to store the cache in the AsyncStorage. @vmurin You can share what is the userId here exactly.

vmurin commented 5 months ago

sure @vmurin. So the userId we get from the response of authorize and acquireSilent doesnot match with the userId we get in our profile APIs. I was calling acquireSilentToken with our profile api userId. I am guessing the userId from the library is a key that is used to store the cache in the AsyncStorage. @vmurin You can share what is the userId here exactly.

The key for the token cache in the AsyncStorage is built based on three parameters: ClientId, UserId and the Scope. The first two are the important ones. Upon extracting the tokens from the cache the scope is checked, so that if your current scope is a subset of the saved scope, the according token will be still extracted.

You can check the function getAccessToken See also save... functions. Actually it should not be needed to use this low level API in a daily practice. Cache handling happen automatically under the hood ;)

Monisankarnath commented 5 months ago

thanks @vmurin . Can we not internally use the userId? Why do we need to send the userId as arg to the acquireSilentToken?

vmurin commented 5 months ago

RefreshTokens have typically long TTL. You could write an app that do some action on behalf of the user in background so that you don't have any context from where you could get current AccessTocken and userID. And in the cache you could have tokens from many different user. That's why it's reasonable to let developer define the UserId to get correct info from the cache.

Monisankarnath commented 5 months ago

Got it. There is one case in our app where the user is logged in first in b2c and then we redirect the user to our domain. Can we use something like the id_token or hash we get from the urlParams to login the user silently with id_token or something when we deeplink it to app with the params? Is it possible in someway?

Monisankarnath commented 5 months ago

Hey @vmurin any solution for the above? In msal browser there is a method ssoSilent using which we can handle a logged in user using the hash and get the tokens on navigating back to our domain.