{"record":{"id":"67d749f9afee2247","repo":"macrozheng/mall-learning","slug":"error-67d749","errorCode":null,"errorMessage":"密码不正确","messagePattern":"密码不正确","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"mall-tiny-05/src/main/java/com/macro/mall/tiny/service/impl/UmsAdminServiceImpl.java","lineNumber":106,"sourceCode":"        }\n        return null;\n    }\n\n    @Override\n    public List<UmsResource> getResourceList() {\n        return resourceList;\n    }\n\n    @Override\n    public String login(String username, String password) {\n        String token = null;\n        try {\n            UserDetails userDetails = getAdminByUsername(username);\n            if(userDetails==null){\n                return token;\n            }\n            if (!passwordEncoder.matches(password, userDetails.getPassword())) {\n                throw new BadCredentialsException(\"密码不正确\");\n            }\n            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());\n            SecurityContextHolder.getContext().setAuthentication(authentication);\n            token = jwtTokenUtil.generateToken(userDetails);\n        } catch (AuthenticationException e) {\n            log.warn(\"登录异常:{}\", e.getMessage());\n        }\n        return token;\n    }\n}\n","sourceCodeStart":88,"sourceCodeEnd":117,"githubUrl":"https://github.com/macrozheng/mall-learning/blob/cd02c000e57c693e49f1f72986dbfa6e4c952e09/mall-tiny-05/src/main/java/com/macro/mall/tiny/service/impl/UmsAdminServiceImpl.java#L88-L117","documentation":"Same as error 5, in mall-tiny-05: login() compares the raw password against the stored BCrypt hash with passwordEncoder.matches and throws BadCredentialsException('密码不正确') on mismatch. The enclosing try/catch (AuthenticationException) logs '登录异常' and returns the still-null token, so the visible symptom is usually an empty token in the response.","triggerScenarios":"Login call with correct username but incorrect password; BCrypt match against the stored hash fails.","commonSituations":"Password typo, seed users inserted with non-BCrypt hashed or plaintext passwords, mismatched PasswordEncoder configuration between registration and login, DB password manually overwritten.","solutions":["Retry with the correct password or reset it using a BCrypt-encoded value","Ensure seed SQL stores BCrypt hashes ($2a$...), not plaintext or MD5","Use the same PasswordEncoder for register and login paths","Surface the BadCredentialsException to the API response instead of swallowing it"],"exampleFix":"// before\n} catch (AuthenticationException e) {\n    log.warn(\"登录异常:{}\", e.getMessage());\n}\nreturn token;\n// after\n} catch (BadCredentialsException e) {\n    log.warn(\"登录异常:{}\", e.getMessage());\n    throw new ApiException(\"密码不正确\");\n}\nreturn token;","handlingStrategy":"try-catch","validationCode":"if (!password) throw new Error('密码不能为空');\n// verify stored format before match\nif (userDetails.getPassword() != null && !userDetails.getPassword().startsWith(\"$2\")) {\n    log.error(\"Non-BCrypt hash stored for user {}\", username);\n}","typeGuard":null,"tryCatchPattern":"try {\n    String token = adminService.login(username, password);\n    if (StrUtil.isEmpty(token)) return CommonResult.validateFailed(\"用户名或密码错误\");\n} catch (BadCredentialsException e) {\n    return CommonResult.validateFailed(\"密码不正确\");\n}","preventionTips":["Keep register and login on the identical PasswordEncoder bean","Seed users only with BCrypt hashes","Treat an empty returned token as a failed login and tell the user","Reset passwords via the app, not raw SQL edits"],"tags":["spring-security","bcrypt","authentication","login"],"backgroundTag":"invalid-credentials","analyzedSha":"cd02c000e57c693e49f1f72986dbfa6e4c952e09","analyzedAt":"2026-09-07T23:16:08.059Z","contentChangedAt":"2026-09-07T23:16:08.059Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}