Open Closed

AccessToken and RefreshToken null #6327


User avatar
0
darutter created
  • ABP Framework version: v7.4.3
  • UI Type: MVC
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace: I have a MAUI app that generates an error (ArgumentNullException) when it attempts to login because the AccessToken and RefreshToken are both null after the call to:

await _storage.GetAsync(<appContstants>.OidcConsts.RefreshTokenKeyName);

The call to the same function using the AccessTokenKeyName returns a token that has expired, but the subsequent call using the RefreshTokenKeyName returns null values. How can I get the RefreshToken to return a valid set of tokens?


1 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    When you log in successfully, it will set accesstoken and refreshtoken.

    public class LoginService : ILoginService, ITransientDependency
    {
        private readonly OidcClient _oidcClient;
        private readonly IStorage _storage;
        private readonly MauiCachedApplicationConfigurationClient _applicationConfigurationClient;
    
        public LoginService(OidcClient oidcClient, IStorage storage, MauiCachedApplicationConfigurationClient applicationConfigurationClient)
        {
            _oidcClient = oidcClient;
            _storage = storage;
            _applicationConfigurationClient = applicationConfigurationClient;
        }
    
        public async Task<LoginResult> LoginAsync()
        {
            var loginResult = await _oidcClient.LoginAsync(new LoginRequest());
    
            if (!loginResult.IsError)
            {
                await SetTokenCacheAsync(loginResult.AccessToken, loginResult.RefreshToken);
                await _applicationConfigurationClient.InitializeAsync();
    
                WeakReferenceMessenger.Default.Send(new LoginMessage());
            }
    
            return loginResult;
        }
    
        public async Task<LogoutResult> LogoutAsync()
        {
            var logoutResult = await _oidcClient.LogoutAsync();
            if (!logoutResult.IsError)
            {
                await ClearTokenCacheAsync();
                await _applicationConfigurationClient.InitializeAsync();
    
                WeakReferenceMessenger.Default.Send(new LogoutMessage());
            }
    
            return logoutResult;
        }
    
        public async Task<string> GetAccessTokenAsync()
        {
            var token = await _storage.GetAsync(MyProjectNameConsts.OidcConsts.AccessTokenKeyName);
    
            if (!token.IsNullOrEmpty())
            {
                var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
                if (jwtToken.ValidTo <= DateTime.UtcNow)
                {
                    var newToken = await TryRefreshTokenAsync();
    
                    if (!newToken.IsNullOrEmpty())
                    {
                        return newToken;
                    }
    
                    await ClearTokenCacheAsync();
                    WeakReferenceMessenger.Default.Send(new LogoutMessage());
                }
            }
    
            return token;
        }
    
        public async Task<string> TryRefreshTokenAsync()
        {
            var refreshToken = await _storage.GetAsync(MyProjectNameConsts.OidcConsts.RefreshTokenKeyName);
            if (!refreshToken.IsNullOrEmpty())
            {
                var refreshResult = await _oidcClient.RefreshTokenAsync(refreshToken);
                await SetTokenCacheAsync(refreshResult.AccessToken, refreshResult.RefreshToken);
    
                return refreshResult.AccessToken;
            }
    
            return string.Empty;
        }
    
        private async Task SetTokenCacheAsync(string accessToken, string refreshToken)
        {
            await _storage.SetAsync(MyProjectNameConsts.OidcConsts.AccessTokenKeyName, accessToken);
            await _storage.SetAsync(MyProjectNameConsts.OidcConsts.RefreshTokenKeyName, refreshToken);
        }
    
        private async Task ClearTokenCacheAsync()
        {
            await _storage.RemoveAsync(MyProjectNameConsts.OidcConsts.AccessTokenKeyName);
            await _storage.RemoveAsync(MyProjectNameConsts.OidcConsts.RefreshTokenKeyName);
        }
    }
    
Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11