JHipster:邮箱密码登录缓存异常问题求助
Hey there, let's break down why both your old and new email addresses are working for login after updating the user's email, even though you've got cache eviction code in place.
First, Let's Recap Your Scenario
- You're using JHipster v4.13.1 with JWT authentication, Ehcache for Spring caching, and H2 disk-persisted dev DB
- Steps to reproduce:
- Log in as
user@localhost - Update email to
user2@localhostvia account settings - Log out, then find both
user@localhostanduser2@localhostcan still log in
- Log in as
- You added temporary cache eviction code in
DomainUserDetailsService.loadUserByUsername(), but theUserService.updateUser()already has cache clearing logic
Likely Root Cause: Missing Eviction for the Old Email in UserService
The most common issue here is that your updateUser() method is only clearing cache entries tied to the new email or the user's login, but not the old email that was replaced. Here's why that matters:
When you update the user's email from user@localhost to user2@localhost, the USERS_BY_EMAIL_CACHE still holds an entry mapping user@localhost to the user record. When you try to log in with the old email, the system pulls that stale cache entry instead of checking the updated DB record.
Check Your UserService.updateUser() Code
Chances are your current code looks something like this (only evicting the new email and login):
// Current (incomplete) code cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(user.getLogin()); cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail());
This misses clearing the old email's cache entry. You need to fetch the original user's data before updating, then evict the old email:
// Corrected code // Fetch the existing user record to get the old email User existingUser = userRepository.findOne(user.getId()); // Evict the old email from the email cache cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(existingUser.getEmail()); // Evict the login from the login cache cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).evict(existingUser.getLogin()); // Optional: Evict the new email too, just in case there's any stale entry cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).evict(user.getEmail());
Other Possible Checks
- Verify Cache Name Consistency: Make sure the constants
UserRepository.USERS_BY_LOGIN_CACHEandUserRepository.USERS_BY_EMAIL_CACHEexactly match the cache names defined in your Ehcache configuration file (e.g.,ehcache.xml). A mismatch means your eviction calls are targeting non-existent caches. - Check JWT Token Expiry: While you mentioned logging out, double-check that your JWT tokens are properly invalidated on logout. Though this is less likely to cause the post-logout login issue, it's worth ruling out.
- Cache Monitoring: Add debug logs in
updateUser()to confirm that cache eviction is actually running. For example:Cache emailCache = cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE); if (emailCache != null) { emailCache.evict(existingUser.getEmail()); log.debug("Evicted old email {} from USERS_BY_EMAIL_CACHE", existingUser.getEmail()); } else { log.error("USERS_BY_EMAIL_CACHE not found!"); }
Why Your Temporary Fix Works
Your code in DomainUserDetailsService.loadUserByUsername() evicts the cache entry for the login/email being used at authentication time. This clears the stale entry right before fetching the user, so the system pulls the fresh DB record instead. However, this is a band-aid—fixing the eviction in updateUser() addresses the problem at its source.
内容的提问来源于stack exchange,提问作者Paul

