On every authenticated request that misses the token-validity cache, JWT validation calls UserManager.IsTokenValidityKeyValidAsync, which delegates to AbpUserStore.IsTokenValidityKeyValidAsync:
public virtual async Task<bool> IsTokenValidityKeyValidAsync(
TUser user, string tokenValidityKey, CancellationToken cancellationToken = default)
{
return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
{
cancellationToken.ThrowIfCancellationRequested();
Check.NotNull(user, nameof(user));
await UserRepository.EnsureCollectionLoadedAsync(user, u => u.Tokens, cancellationToken);
return user.Tokens.Any(t => t.LoginProvider == TokenValidityKeyProvider &&
t.Name == tokenValidityKey &&
t.ExpireDate > DateTime.UtcNow);
});
}
EnsureCollectionLoadedAsync(user, u => u.Tokens) issues SELECT * FROM AbpUserTokens WHERE UserId = @id and materializes every token row for that user. The LoginProvider / Name / ExpireDate filter then runs in memory (client-side) via .Any(...) — it is never translated to SQL.
So, is there a reason the existence check is done by loading the full collection rather than a filtered query? Would the team consider changing the framework implementation to a server-side existence query?
Thanks.
1 Answer(s)
-
0
Hi @npdevs
Thank you for reporting this. We have created an issue to track the performance problem and will work on a fix as soon as possible.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image)