소스 검색

fix 密码强校验,微信登录后台账号返回token

Administrator 1 년 전
부모
커밋
3395f5653a

+ 9 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java

@@ -32,6 +32,8 @@ import com.ruoyi.system.service.ISysPostService;
 import com.ruoyi.system.service.ISysRoleService;
 import com.ruoyi.system.service.ISysUserService;
 
+import static com.ruoyi.common.utils.SecurityUtils.checkStrongPwd;
+
 /**
  * 用户信息
  * 
@@ -136,6 +138,9 @@ public class SysUserController extends BaseController
         {
             return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
         }
+        else if ("1".equals(checkStrongPwd(user.getPassword()))) {
+            return AjaxResult.error("密码必须包含数字、大小写字母、特殊符号且大于8位");
+        }
         user.setCreateBy(getUsername());
         user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
         return toAjax(userService.insertUser(user));
@@ -190,7 +195,10 @@ public class SysUserController extends BaseController
     @PutMapping("/resetPwd")
     public AjaxResult resetPwd(@RequestBody SysUser user)
     {
-        userService.checkUserAllowed(user);
+        if ("1".equals(checkStrongPwd(user.getPassword()))) {
+            return AjaxResult.error("密码必须包含数字、大小写字母、特殊符号且大于8位");
+        }
+        //userService.checkUserAllowed(user);
         userService.checkUserDataScope(user.getUserId());
         user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
         user.setUpdateBy(getUsername());

+ 43 - 5
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wx/WxPayController.java

@@ -1,14 +1,30 @@
 package com.ruoyi.web.controller.wx;
 
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.model.LoginUser;
+import com.ruoyi.common.enums.UserStatus;
+import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.ServletUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.ip.IpUtils;
+import com.ruoyi.common.utils.uuid.IdUtils;
+import com.ruoyi.framework.web.service.SysLoginService;
 import com.ruoyi.system.domain.wx.AppletLoginForm;
 import com.ruoyi.system.domain.wx.AppletSessionDTO;
 import com.ruoyi.system.domain.wx.WxPayOrderReqVo;
 import com.ruoyi.system.domain.wx.WxPayRespVo;
 import com.ruoyi.system.service.ISysPostService;
+import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.system.service.IWxPayService;
 import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -16,6 +32,9 @@ import utils.WxCodeSessionUtil;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @Author: tjf
@@ -26,6 +45,12 @@ import javax.servlet.http.HttpServletRequest;
 @RequestMapping("/wx/pay")
 public class WxPayController extends BaseController {
 
+    @Autowired
+    private SysLoginService loginService;
+
+    @Autowired
+    private ISysUserService userService;
+
     @Resource
     private IWxPayService wxPayService;
 
@@ -37,7 +62,7 @@ public class WxPayController extends BaseController {
 
     @ApiOperation(value = "微信支付回调", notes = "微信支付回调")
     @PostMapping("/payNotify")
-    public AjaxResult payNotify(HttpServletRequest request){
+    public AjaxResult payNotify(HttpServletRequest request) {
         //注意:回调接口需要暴露到公网上,且要放开token验证
         wxPayService.payNotify(request);
         return AjaxResult.success();
@@ -45,12 +70,25 @@ public class WxPayController extends BaseController {
 
     /**
      * 小程序登录
-     * @param  form
+     *
+     * @param form
      * @return
      */
     @PostMapping("/jsCode")
-    public AjaxResult code2Session(@RequestBody AppletLoginForm form){
-        AppletSessionDTO appletSessionDTO = WxCodeSessionUtil.jscode2Session(form);
-        return AjaxResult.success(appletSessionDTO);
+    public AjaxResult code2Session(@RequestBody AppletLoginForm form) {
+        AjaxResult ajax = AjaxResult.success();
+        AppletSessionDTO dto = WxCodeSessionUtil.jscode2Session(form);
+        ajax.put(Constants.APPLETSESSIONDTO, dto);
+        String phoneNumber = dto.getPhoneNumber();
+        if (StringUtils.isBlank(phoneNumber)) {
+            throw new BaseException("对不起,未获取到手机号");
+        }
+        SysUser user = userService.getByPhone(phoneNumber);
+        if (user != null) {
+            // 生成令牌
+            String token = loginService.loginMiniPrograms(user.getUserName(), user.getPassword());
+            ajax.put(Constants.TOKEN, token);
+        }
+        return ajax;
     }
 }

+ 4 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java

@@ -93,6 +93,10 @@ public class Constants
      * 令牌
      */
     public static final String TOKEN = "token";
+    /**
+     * 微信登录相关信息
+     */
+    public static final String APPLETSESSIONDTO = "appletsessiondto";
 
     /**
      * 令牌前缀

+ 111 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/PwdCheckUtil.java

@@ -0,0 +1,111 @@
+package com.ruoyi.common.utils;
+
+/**
+ * @Author: tjf
+ * @Date: 2022/10/10 9:24
+ * @Describe:
+ */
+public class PwdCheckUtil {
+    //定义特殊字符
+    public static String SPECIAL_CHAR = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
+
+    /**
+     * @brief   检测密码中字符长度
+     * @param[in] password            密码字符串
+     * @return  符合长度要求 返回true
+     */
+    public static boolean checkPasswordLength(String password, String minNum, String maxNum) {
+        boolean flag =false;
+        if (StringUtils.isBlank(maxNum))  {
+            minNum = StringUtils.isBlank(minNum) ? "0":minNum;
+            if (password.length() >= Integer.parseInt(minNum)) {
+                flag = true;
+            }
+        } else {
+            minNum = StringUtils.isBlank(minNum) ? "0":minNum;
+            if (password.length() >= Integer.parseInt(minNum) &&
+                    password.length() <= Integer.parseInt(maxNum)) {
+                flag = true;
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * @brief   检测密码中是否包含数字
+     * @param[in] password            密码字符串
+     * @return  包含数字 返回true
+     */
+    public static boolean checkContainDigit(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isDigit(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @brief   检测密码中是否包含字母(不区分大小写)
+     * @param[in] password            密码字符串
+     * @return  包含字母 返回true
+     */
+    public static boolean checkContainCase(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isLetter(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @brief   检测密码中是否包含小写字母
+     * @param[in] password            密码字符串
+     * @return  包含小写字母 返回true
+     */
+    public static boolean checkContainLowerCase(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isLowerCase(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @brief   检测密码中是否包含大写字母
+     * @param[in] password            密码字符串
+     * @return  包含大写字母 返回true
+     */
+    public static boolean checkContainUpperCase(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (Character.isUpperCase(chPass[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @brief   检测密码中是否包含特殊符号
+     * @param[in] password            密码字符串
+     * @return  包含特殊符号 返回true
+     */
+    public static boolean checkContainSpecialChar(String password) {
+        char[] chPass = password.toCharArray();
+        for (int i = 0; i < chPass.length; i++) {
+            if (SPECIAL_CHAR.indexOf(chPass[i]) != -1) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 26 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java

@@ -3,6 +3,9 @@ package com.ruoyi.common.utils;
 import java.util.Collection;
 import java.util.List;
 import java.util.stream.Collectors;
+
+
+import jdk.internal.util.Preconditions;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -175,4 +178,27 @@ public class SecurityUtils
                 .anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role));
     }
 
+    /**
+     * @brief   检测密码复杂度是否为 强
+     * @param[in] password  密码字符串
+     * @return  符合长度要求 返回true
+     */
+    public static String checkStrongPwd(String pwd) {
+        try {
+            if (StringUtils.isNotEmpty(pwd)){
+                if (!PwdCheckUtil.checkPasswordLength(pwd, "8", null)
+                        || !PwdCheckUtil.checkContainLowerCase(pwd)
+                        || !PwdCheckUtil.checkContainUpperCase(pwd)
+                        || !PwdCheckUtil.checkContainDigit(pwd)
+                        || !PwdCheckUtil.checkContainSpecialChar(pwd)
+                ) {
+                    return "1";
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "0";
+    }
+
 }

+ 47 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java

@@ -100,6 +100,53 @@ public class SysLoginService
         return tokenService.createToken(loginUser);
     }
 
+    /**
+     * 登录验证
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @param code 验证码
+     * @param uuid 唯一标识
+     * @return 结果
+     */
+    public String loginMiniPrograms(String username, String password)
+    {
+
+        // 登录前置校验
+        loginPreCheck(username, password);
+        // 用户验证
+        Authentication authentication = null;
+        try
+        {
+            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
+            AuthenticationContextHolder.setContext(authenticationToken);
+            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+            authentication = authenticationManager.authenticate(authenticationToken);
+        }
+        catch (Exception e)
+        {
+            if (e instanceof BadCredentialsException)
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                throw new UserPasswordNotMatchException();
+            }
+            else
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+                throw new ServiceException(e.getMessage());
+            }
+        }
+        finally
+        {
+            AuthenticationContextHolder.clearContext();
+        }
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        recordLoginInfo(loginUser.getUserId());
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }
+
     /**
      * 校验验证码
      * 

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java

@@ -124,4 +124,6 @@ public interface SysUserMapper
      * @return 结果
      */
     public SysUser checkEmailUnique(String email);
+
+    SysUser getByPhone(String phone);
 }

+ 8 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -203,4 +203,12 @@ public interface ISysUserService
      * @return 结果
      */
     public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
+
+    /**
+     * 功能描述: getByPhone
+     *
+     * @param phone phone
+     * @return com.boman.domain.SysUser
+     */
+    SysUser getByPhone(String phone);
 }

+ 10 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -541,4 +541,14 @@ public class SysUserServiceImpl implements ISysUserService
         }
         return successMsg.toString();
     }
+    /**
+     * 功能描述: getByPhone
+     *
+     * @param phone phone
+     * @return com.boman.domain.SysUser
+     */
+    @Override
+    public SysUser getByPhone(String phone) {
+        return userMapper.getByPhone(phone);
+    }
 }

+ 0 - 2
ruoyi-system/src/main/java/utils/WxCodeSessionUtil.java

@@ -64,8 +64,6 @@ public class WxCodeSessionUtil {
         // unionId有可能是空
         appletSession.setUnionId(result.getString("unionid"));
         appletSession.setSessionKey(result.getString("session_key"));
-
-        System.out.println();
         String phoneNumber = getPhoneNumber(form, appletSession);
         appletSession.setPhoneNumber(phoneNumber);
         return appletSession;

+ 4 - 1
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -217,5 +217,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			#{userId}
         </foreach> 
  	</delete>
-	
+	<select id="getByPhone" resultMap="SysUserResult">
+		<include refid="selectUserVo"/>
+		where u.phonenumber = #{phone}  and u.del_flag = '0' limit 1;
+	</select>
 </mapper>