Przeglądaj źródła

fix: 管理员登录兼容 BCrypt 密码验证 + 新管理员密码用 BCrypt

Xiaogang Liao 1 miesiąc temu
rodzic
commit
ac0cdfc09a

+ 27 - 7
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminAuthController.java

@@ -2,6 +2,7 @@ package com.etotem.cfc.controller.admin;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.etotem.cfc.common.Result;
 import com.etotem.cfc.common.Result;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import com.etotem.cfc.config.JwtConfig;
 import com.etotem.cfc.config.JwtConfig;
 import com.etotem.cfc.dto.AdminLoginDTO;
 import com.etotem.cfc.dto.AdminLoginDTO;
 import com.etotem.cfc.dto.SendCodeDTO;
 import com.etotem.cfc.dto.SendCodeDTO;
@@ -27,6 +28,8 @@ import java.util.Map;
 @RequestMapping("/api/admin-auth")
 @RequestMapping("/api/admin-auth")
 public class AdminAuthController {
 public class AdminAuthController {
 
 
+    private static final BCryptPasswordEncoder BC_PASSWORD_ENCODER = new BCryptPasswordEncoder();
+
     @Resource
     @Resource
     private UserMapper userMapper;
     private UserMapper userMapper;
 
 
@@ -268,13 +271,8 @@ public class AdminAuthController {
             return Result.error("用户不存在");
             return Result.error("用户不存在");
         }
         }
 
 
-        // 验证密码(兼容两种hash方式)
-        java.nio.charset.Charset utf8 = java.nio.charset.StandardCharsets.UTF_8;
-        String hash1 = org.springframework.util.DigestUtils.md5DigestAsHex(
-                ("xzyj_salt_" + dto.getPassword()).getBytes(utf8));
-        String hash2 = org.springframework.util.DigestUtils.md5DigestAsHex(
-                ("xzyj_admin_salt_" + dto.getPassword()).getBytes(utf8));
-        if (!hash1.equals(user.getPassword()) && !hash2.equals(user.getPassword())) {
+        // 验证密码(兼容 MD5 与 BCrypt 两种哈希方式)
+        if (!verifyLoginPassword(dto.getPassword(), user.getPassword())) {
             loginAttemptService.recordFailure(lockKey);
             loginAttemptService.recordFailure(lockKey);
             int remaining = loginAttemptService.getRemainingAttempts(lockKey);
             int remaining = loginAttemptService.getRemainingAttempts(lockKey);
             return Result.error("密码错误,剩余" + remaining + "次尝试机会");
             return Result.error("密码错误,剩余" + remaining + "次尝试机会");
@@ -331,4 +329,26 @@ public class AdminAuthController {
         }
         }
         return ip;
         return ip;
     }
     }
+
+    /**
+     * 验证登录密码:兼容旧 MD5 哈希与新 BCrypt 哈希
+     * MD5 格式:xzyj_salt_{password} 或 xzyj_admin_salt_{password}
+     * BCrypt 格式:$2a$...$...
+     */
+    private boolean verifyLoginPassword(String rawPassword, String storedHash) {
+        if (storedHash == null || storedHash.isEmpty()) {
+            return false;
+        }
+        // BCrypt 哈希
+        if (storedHash.startsWith("$2a$") || storedHash.startsWith("$2b$")) {
+            return BC_PASSWORD_ENCODER.matches(rawPassword, storedHash);
+        }
+        // 旧 MD5 哈希(兼容两种盐值)
+        java.nio.charset.Charset utf8 = java.nio.charset.StandardCharsets.UTF_8;
+        String hash1 = org.springframework.util.DigestUtils.md5DigestAsHex(
+                ("xzyj_salt_" + rawPassword).getBytes(utf8));
+        String hash2 = org.springframework.util.DigestUtils.md5DigestAsHex(
+                ("xzyj_admin_salt_" + rawPassword).getBytes(utf8));
+        return hash1.equals(storedHash) || hash2.equals(storedHash);
+    }
 }
 }

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java

@@ -715,7 +715,7 @@ public class AdminController {
             admin.setNickname(user.getNickname());
             admin.setNickname(user.getNickname());
             admin.setRole("teacher");
             admin.setRole("teacher");
             admin.setStatus(1);
             admin.setStatus(1);
-            admin.setPassword(DigestUtils.md5DigestAsHex(("xzyj_admin_salt_" + user.getPhone()).getBytes()));
+            admin.setPassword(new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder().encode(user.getPhone()));
             admin.setCreatedAt(new Date());
             admin.setCreatedAt(new Date());
             admin.setUpdatedAt(new Date());
             admin.setUpdatedAt(new Date());
             adminMapper.insert(admin);
             adminMapper.insert(admin);