Ver Fonte

验证码登录

skyfffire há 2 meses atrás
pai
commit
249b0f2471

+ 56 - 41
src/main/java/modules/user/UserController.java

@@ -31,15 +31,7 @@ public class UserController extends MyController {
         JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
 
         // 从 JSON 对象中获取 mobile_number
-        String mobileNumber = requestBodyJson.getString("mobile_number");
-
-        // 走到这里时,EmptyInterceptor 已经保证了 mobile_number 不会是 StrKit.isBlank()
-
-        // 1. 校验手机号是否被注册
-        if (service.isUserExists(mobileNumber)) {
-            renderJson(MyRet.fail("该手机号已被注册。"));
-            return;
-        }
+//        String mobileNumber = requestBodyJson.getString("mobile_number");
 
         // 2. 校验发送间隔
         // 从 Session 中获取上次发送验证码的时间戳
@@ -93,37 +85,13 @@ public class UserController extends MyController {
         }
 
         // 3. 验证码校验
-        String storedVerifyCode = getSessionAttr("verify_code");
-        Long sendTime = getSessionAttr("last_send_verify_code_time");
-
-        if (StrKit.isBlank(storedVerifyCode) || sendTime == null) {
-            // Session中没有验证码或发送时间,可能从未发送过,或Session已失效/过期
-            renderJson(MyRet.fail("请先获取验证码或验证码已失效"));
+        MyRet verifyCodeRet = checkVerifyCode(userVerifyCode);
+        if (!verifyCodeRet.isOk()) {
+            renderJson(verifyCodeRet);
             return;
         }
 
-        // 校验有效期
-        long currentTime = System.currentTimeMillis();
-        if (currentTime - sendTime > VERIFY_CODE_EXPIRATION_TIME) {
-            // 验证码已过期
-            // 可以在这里清除Session中的验证码,防止不必要的存储
-            removeSessionAttr("verify_code");
-            removeSessionAttr("last_send_verify_code_time");
-            renderJson(MyRet.fail("验证码已过期,请重新获取"));
-            return;
-        }
-
-        // 校验用户输入的验证码是否与Session中存储的一致
-        if (!userVerifyCode.equals(storedVerifyCode)) {
-            renderJson(MyRet.fail("验证码不正确"));
-            return;
-        }
-
-        // 4. (重要) 验证码使用后即失效
-        // 成功验证后立即清除Session中的验证码,防止被重复使用
-        removeSessionAttr("verify_code");
-
-        // 5. 构建 User 对象并处理业务逻辑
+        // 4. 构建 User 对象并处理业务逻辑
         // 因为 getPara("mobile_number") 已经获取了手机号,这里可以手动设置
         // 或者优化 getModel 的用法,让它只获取数据库字段,然后手动设置 mobileNumber。
         // 但为了保持原先 getModel 的语义,这里继续使用。
@@ -142,11 +110,11 @@ public class UserController extends MyController {
         user.set("integral", 0);
         user.set("is_deleted", 0); // 0表示未禁用
 
-        // 6. 调用服务层进行用户保存
+        // 5. 调用服务层进行用户保存
         renderJson(service.saveUser(user));
     }
 
-    @EmptyInterface(keyArray = {"mobile_number", "pwd_md5"})
+    @EmptyInterface(keyArray = {"mobile_number"})
     public void login() {
         // --- 核心修改部分:从 JSON 请求体中获取参数 ---
         JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
@@ -154,14 +122,30 @@ public class UserController extends MyController {
         // 因为 EmptyInterceptor 已经保证了这些字段不为空,这里可以直接获取
         String mobileNumber = requestBodyJson.getString("mobile_number");
         String pwdMd5 = requestBodyJson.getString("pwd_md5");
+        String verifyCode = requestBodyJson.getString("verify_code");
 
         // 1. 校验手机号是否被注册
         if (!service.isUserExists(mobileNumber)) {
             renderJson(MyRet.fail("该手机号未注册。"));
             return;
         }
-
-        MyRet ret = service.login(mobileNumber, HashKit.md5(pwdMd5));
+        
+        // 2.判断是使用密码还是验证码登录
+        MyRet ret = MyRet.fail("违规操作会导致ip封禁!");
+        // 如果传入了密码优先使用密码登录
+        if (!StrKit.isBlank(pwdMd5)) {
+            ret = service.login(mobileNumber, HashKit.md5(pwdMd5));
+        } 
+        // 如果有验证码传入进行验证码校验
+        if (!StrKit.isBlank(verifyCode)) {
+            MyRet verifyCodeRet = checkVerifyCode(verifyCode);
+            if (!verifyCodeRet.isOk()) {
+                renderJson(verifyCodeRet);
+                return;
+            }
+            
+            ret = service.verifyCodeLogin(mobileNumber);
+        }
         
         if (ret.isOk()) {
             ret.set("token", createToken("dl-token"));
@@ -173,4 +157,35 @@ public class UserController extends MyController {
         
         renderJson(ret);
     }
+    
+    private MyRet checkVerifyCode(String userVerifyCode) {
+        // 3. 验证码校验
+        String storedVerifyCode = getSessionAttr("verify_code");
+        Long sendTime = getSessionAttr("last_send_verify_code_time");
+
+        if (StrKit.isBlank(storedVerifyCode) || sendTime == null) {
+            // Session中没有验证码或发送时间,可能从未发送过,或Session已失效/过期
+            return MyRet.fail("请先获取验证码或验证码已失效");
+        }
+
+        // 校验有效期
+        long currentTime = System.currentTimeMillis();
+        if (currentTime - sendTime > VERIFY_CODE_EXPIRATION_TIME) {
+            // 验证码已过期
+            // 可以在这里清除Session中的验证码,防止不必要的存储
+            removeSessionAttr("verify_code");
+            removeSessionAttr("last_send_verify_code_time");
+            return MyRet.fail("验证码已过期,请重新获取");
+        }
+
+        // 校验用户输入的验证码是否与Session中存储的一致
+        if (!userVerifyCode.equals(storedVerifyCode)) {
+            renderJson(MyRet.fail("验证码不正确"));
+            return MyRet.fail("验证码已过期,请重新获取");
+        }
+
+        removeSessionAttr("verify_code");
+        
+        return MyRet.ok("验证码校验通过");
+    }
 }

+ 18 - 1
src/main/java/modules/user/UserService.java

@@ -23,7 +23,7 @@ public class UserService {
     }
     
     public MyRet login(String mobileNumber, String pwdMd5Md5) {
-        String findSQL = "select id, mobile_number, role from t_user where "
+        String findSQL = "select id, nickname, mobile_number, role, referrer_id, integral, create_time, update_time, is_deleted from t_user where "
                 + "mobile_number = ? and pwd_md5_md5=?";
         User u = User.dao.findFirst(findSQL, mobileNumber, pwdMd5Md5);
 
@@ -34,6 +34,23 @@ public class UserService {
         }
     }
     
+    public MyRet verifyCodeLogin(String mobileNumber) {
+        User u = findUserByMobileNumber(mobileNumber);
+
+        if (u == null) {
+            return MyRet.fail("验证码登录失败,违规操作将封禁ip。");
+        } else {
+            return MyRet.ok("登录成功。").setData(u);
+        }
+    }
+    
+    public User findUserByMobileNumber(String MobileNumber) {
+        String columns = "id, nickname, mobile_number, role, referrer_id, integral, create_time, update_time, is_deleted";
+        String sql = "select " + columns + " from t_user where mobile_number = ?";
+        
+        return User.dao.findFirst(sql, MobileNumber);
+    }
+    
     public boolean isUserExists(String mobileNumber) {        
         return Db.queryLong("SELECT COUNT(1) FROM t_user WHERE mobile_number = ?", mobileNumber) > 0;
     }

+ 4 - 3
src/test/rest/UserControllerTest.http

@@ -14,14 +14,15 @@ Content-Type: application/json
   "mobile_number": "17781855864",
   "pwd_md5": "e10adc3949ba59abbe56e057f20f883e",
   "repeat_pwd_md5": "e10adc3949ba59abbe56e057f20f883e",
-  "verify_code": "2529"
+  "verify_code": "9119"
 }
 
-### 登录
+### 登录,可以选择传入pwd_md5(密码登录)或verify_code(验证码登录)。如果两者都传入了,后台会优先使用pwd_md5
 POST {{ baseUrl }}/user/login
 Content-Type: application/json
 
 {
   "mobile_number": "17781855864",
-  "pwd_md5": "e10adc3949ba59abbe56e057f20f883e"
+  "pwd_md5": "e10adc3949ba59abbe56e057f20f883e",
+  "verify_code": ""
 }