macrozheng/mall · error · UsernameNotFoundException

用户名或密码错误

Error message

用户名或密码错误

What it means

This is the UserDetailsService.loadUserByUsername contract implemented by the mall-portal member service (front-end/customer accounts). It calls getByUsername(username) to look up a UmsMember; when none is found it throws UsernameNotFoundException. This method is invoked both by Spring Security during portal authentication and directly by UmsMemberServiceImpl.login (line ~166), so the same throw surfaces on both interactive login and programmatic authenticate-by-token flows.

Source

Thrown at mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java:161

        return memberDetails.getUmsMember();
    }

    @Override
    public void updateIntegration(Long id, Integer integration) {
        UmsMember record=new UmsMember();
        record.setId(id);
        record.setIntegration(integration);
        memberMapper.updateByPrimaryKeySelective(record);
        memberCacheService.delMember(id);
    }

    @Override
    public UserDetails loadUserByUsername(String username) {
        UmsMember member = getByUsername(username);
        if(member!=null){
            return new MemberDetails(member);
        }
        throw new UsernameNotFoundException("用户名或密码错误");
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        //密码需要客户端加密后传递
        try {
            UserDetails userDetails = loadUserByUsername(username);
            if(!passwordEncoder.matches(password,userDetails.getPassword())){
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;

View on GitHub (pinned to 0504e86b1f)

Solutions

  1. Confirm the member exists: SELECT id,username,phone FROM ums_member WHERE username = ? (or by phone depending on getByUsername).
  2. Verify the registration flow actually persisted the member and that the client is logging in with the same identifier used at registration.
  3. Flush the member cache (memberCacheService.delMember / cache keys) in case a stale null is cached for the username.
  4. Catch UsernameNotFoundException together with BadCredentialsException in the login path and return a single generic error to avoid account enumeration.
  5. If login by phone or email is required, ensure getByUsername resolves the alternate identifier or extend it to do so.

Example fix

// before (login swallows only AuthenticationException):
try {
    UserDetails userDetails = loadUserByUsername(username);
    if (!passwordEncoder.matches(password, userDetails.getPassword())) {
        throw new BadCredentialsException("密码不正确");
    }
    ...
} catch (AuthenticationException e) {
    LOGGER.warn("登录异常:{}", e.getMessage());
}

// after (explicit null-check, unified message):
UmsMember member = getByUsername(username);
if (member == null || !passwordEncoder.matches(password, member.getPassword())) {
    LOGGER.warn("登录失败, username={}", username);
    throw new BadCredentialsException("用户名或密码错误");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Resolve the member up front and short-circuit with a generic message so the
// portal never distinguishes 'no such member' from 'wrong password'.
UmsMember member = memberService.getByUsername(username);
if (member == null) {
    return CommonResult.validateFailed("用户名或密码错误");
}

Try / catch

// login() currently catches AuthenticationException and returns null; at the
// controller, treat null token as a failed login with a single message.
String token = memberService.login(username, password);
if (token == null) {
    return CommonResult.validateFailed("用户名或密码错误");
}

Prevention

When it happens

Trigger: Portal login with a username that was never registered; login attempt after the member account was deleted; the member Redis cache (memberCacheService) returning stale data for a removed member; calling login() programmatically with a token-less, non-existent username.

Common situations: Customer mistypes the registered username or uses the wrong login type (phone vs username); registration silently failed so the member row never persisted; member record deleted by an admin/cleanup job while the user's app still tries to log in; DB or MyBatis misconfiguration making getByUsername return null.

Related errors


AI-assisted analysis of macrozheng/mall@0504e86b1f (2026-08-13). Data as JSON: /api/errors/7b9c18cbf1752562. Report an issue: GitHub.