This commit is contained in:
lijiaqi 2023-08-28 17:37:38 +08:00
parent cdb83e844d
commit e267e1fec2
6 changed files with 509 additions and 9 deletions

View File

@ -0,0 +1,61 @@
package com.ydool.common.utils;
import com.ydool.common.exception.ResultException;
public class LoginNameUtil {
/**
* 检查用户名规则
*
* @param userName
* @return
*/
public static String checkp(String userName) {
//用户名必须为6-20位
if (userName.length() < 6 || userName.length() > 20) {
return "用户名必须为6-20位";
}
// 用户名只能包含数字字母和下划线
String str = "^[a-zA-Z0-9_]+$";
if (!userName.matches(str)) {
return "用户名只能包含数字、字母和下划线";
}
// 用户名不能以数字开头
String str1 = "^[a-zA-Z_][a-zA-Z0-9_]*$";
if (!userName.matches(str1)) {
return "用户名不能以数字开头";
}
return "ok";
}
/**
* 检查用户名是否包含关键字
*
* @param userName
* @return
*/
public static String checkKeyword(String userName) {
//忽略大小写关键字为admin,system,ydool,833457,6500189
String[] keywords = {"admin", "system", "ydool", "833457", "6500189"};
for (String keyword : keywords) {
if (userName.toLowerCase().contains(keyword)) {
return "用户名包含关键字";
}
}
return "ok";
}
public static Boolean valid(String userName) {
//用户名规则
String check = checkp(userName);
//用户名是否包含关键字
String checkKeyword = checkKeyword(userName);
if (!"ok".equals(check)) {
throw new ResultException(check);
} else if (!"ok".equals(checkKeyword)) {
throw new ResultException(checkKeyword);
} else {
return true;
}
}
}

View File

@ -1,5 +1,8 @@
package com.ydool.common.utils; package com.ydool.common.utils;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.util.StringUtils;
import com.ydool.common.exception.ResultException;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -7,13 +10,284 @@ import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import java.security.Key; import java.security.Key;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class PasswordUtil { public class PasswordUtil {
public static Boolean valid(String password) { /***
String regexp = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,24}$"; * 描述: 三个或者三个以上相同
return Pattern.matches(regexp, password); *
* @param pwd 密码
* @return String
*/
public static String check3(String pwd) {
String regx = "^.*(.)\\1{2}.*$";
Matcher m = null;
Pattern p = null;
p = Pattern.compile(regx);
m = p.matcher(pwd);
if (m.matches()) {
return "密码包含三个或者三个以上相同";
} else {
return "ok";
}
}
/***
* 描述: 验证生日 身份证
*
* @param pwd 密码
* @return String
*/
public static String checkBirthday(String pwd) {
String birthday = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)";
Pattern pattern = Pattern.compile(birthday);
Matcher matcher = pattern.matcher(pwd);
if (matcher.find()) {
return "密码包含生日或者身份证";
} else {
return "ok";
}
}
/***
* 描述: 密码规则
*
* @param pwd 密码
* @return String
*/
public static String checkp(String pwd) {
String str = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{18,36}$";
if (!pwd.matches(str)) {
return "密码至少由18位及以上大小写字母、数字及特殊字符等混合、随机组成(至少包括数字、小写字母、大写字母和特殊符号各一个),最长36位";
} else {
return "ok";
}
}
/***
* 描述: 密码是否密码包含关键字
*
* @param pwd 密码
* @return String
*/
public static String checkKeyword(String pwd) {
//忽略大小写关键字为admin,system,ydool,833457,6500189
String[] keywords = {"admin", "system", "ydool", "833457", "6500189"};
for (String keyword : keywords) {
if (pwd.toLowerCase().contains(keyword)) {
return "密码包含关键字";
}
}
return "ok";
}
/***
* 描述: 验证密码
*
* @param pwd 密码
* @return String
*/
public static Boolean valid(String pwd) {
//密码规则
String check = checkp(pwd);
//键盘上连续3位或者以上
String rsThree = validateKey(pwd);
String repeat = checkRepeat(pwd);
//密码包含生日
String checkBirthday = checkBirthday(pwd);
//三个或者三个以上相同
String check3 = check3(pwd);
//密码包含手机号
String checkMobile = checkMobile(pwd);
//密码包含固定电话
String checkPhone = checkPhone(pwd);
//密码包含关键字
String checkKeyword = checkKeyword(pwd);
if (!"ok".equals(check)) {
throw new ResultException(check);
} else if (!"ok".equals(rsThree)) {
throw new ResultException(rsThree);
} else if (!"ok".equals(repeat)) {
throw new ResultException(repeat);
} else if (!"ok".equals(checkBirthday)) {
throw new ResultException(checkBirthday);
} else if (!"ok".equals(check3)) {
throw new ResultException(check3);
} else if (!"ok".equals(checkMobile)) {
throw new ResultException(checkMobile);
} else if (!"ok".equals(checkPhone)) {
throw new ResultException(checkPhone);
} else {
return true;
}
}
/***
* 描述: 密码是否密码包含手机号
*
* @param sParam 密码
* @return String
*/
public static String checkMobile(String sParam) {
if (sParam.length() <= 0)
return "";
Pattern pattern = Pattern.compile("(1|861)(3|4|5|6||7|8|9)\\d{9}$*");
Matcher matcher = pattern.matcher(sParam);
StringBuffer bf = new StringBuffer();
while (matcher.find()) {
bf.append(matcher.group()).append(",");
}
int len = bf.length();
if (len > 0) {
bf.deleteCharAt(len - 1);
}
if (StrUtil.isNotBlank(bf.toString())) {
return "密码包含手机号";
} else {
return "ok";
}
}
/***
* 描述: 密码包含固定电话
*
* @param content 电话
* @return String
*/
public static String checkPhone(String content) {
List<String> list = new ArrayList<>();
Pattern p = Pattern.compile("\\d{3}-\\d{8}|\\d{4}-\\d{6}|\\d{7}|\\d{8}");
Matcher matcher = p.matcher(content);
while (matcher.find()) {
String n = matcher.group(0).toString();
list.add(n);
}
if (!list.isEmpty()) {
return "密码包含固定电话";
} else {
return "ok";
}
}
/***
* 描述: 密码不得密码包含键盘上任意连续的三个字符或shift转换字符
*
* @param str 字符串
* @return String
*/
public static String validateKey(String str) {
//定义横向穷举
String[][] keyCode = {
{"`~·", "1=", "2@@", "3#", "4$¥", "5%", "6^……", "7&", "8*", "9(", "0)", "-_", "=+"},
{" ", "qQ", "wW", "eE", "rR", "tT", "yY", "uU", "iI", "oO", "pP", "[{【", "]}】", "\\|、"},
{" ", "aA", "sS", "dD", "fF", "gG", "hH", "jJ", "kK", "lL", ";:", "\'\"’“"},
{" ", "zZ", "xX", "cC", "vV", "bB", "nN", "mM", ",《<", ".>》", "/?"}
};
//找出给出的字符串每个字符在坐标系中的位置
char[] c = str.toCharArray();
List<Integer> x = new ArrayList<Integer>();
List<Integer> y = new ArrayList<Integer>();
for (int i = 0; i < c.length; i++) {
char temp = c[i];
toHere:
for (int j = 0; j < keyCode.length; j++) {
for (int k = 0; k < keyCode[j].length; k++) {
String jk = keyCode[j][k];
if (jk.contains(String.valueOf(temp))) {
x.add(j);
y.add(k);
break toHere;
}
}
}
}
boolean flag = false;
for (int i = 0; i < x.size() - 2; i++) {
// 如果X一致那么就是在一排
if (x.get(i) == x.get(i + 1) && x.get(i + 1) == x.get(i + 2)) {//四者在同一行上
if (y.get(i) > y.get(i + 2)) {
if (y.get(i) - 1 == y.get(i + 1) && y.get(i) - 2 == y.get(i + 2)) {
flag = true;
break;
}
} else {
if (y.get(i) + 1 == y.get(i + 1) && y.get(i) + 2 == y.get(i + 2)) {
flag = true;
break;
}
}
} else if (x.get(i) != x.get(i + 1)
&& x.get(i + 1) != x.get(i + 2)
&& x.get(i) != x.get(i + 2)
) {//四者均不在同一行上,但是如果y相同说明是一列
if (y.get(i) == y.get(i + 1) && y.get(i + 1) == y.get(i + 2)) {
flag = true;
break;
}
}
}
if (flag) {
return "密码不能连续三个或者三个以上字符";
} else {
return "ok";
}
}
/**
* 转码
*
* @param c 字符
* @return 编码
*/
public static int getUnicode(char c) {
String returnUniCode = null;
returnUniCode = String.valueOf((int) c);
return Integer.parseInt(returnUniCode);
}
/***
* 描述: 不能连续字符如123abc连续3位或3位以上
*
* @param str 字符串
* @return String
*/
public static String checkRepeat(String str) {
String[] arr = str.split("");
boolean flag = false;
for (int i = 1; i < arr.length - 1; i++) {
int firstIndex = getUnicode(arr[i - 1].charAt(0));
int secondIndex = getUnicode(arr[i].charAt(0));
int thirdIndex = getUnicode(arr[i + 1].charAt(0));
if ((thirdIndex - secondIndex == 1) && (secondIndex - firstIndex == 1)) {
flag = true;
}
}
if (flag) {
return "密码不能连续3字母";
} else {
return "ok";
}
} }
public static String password(String salt, String src){ public static String password(String salt, String src){

View File

@ -118,7 +118,7 @@ public class AuthServiceImpl extends BaseService<UserMapper, User> implements IA
//是否需要强制修改密码 //是否需要强制修改密码
result.set("need_init_password", password.equals(ConfigCache.getStr(ConfigCache.USER_INIT_PASSWORD, result.set("need_init_password", password.equals(ConfigCache.getStr(ConfigCache.USER_INIT_PASSWORD,
"888888")) ? true : false); "Siwhnd!@Lc2349#!Rdisabled")) ? true : false);
return AjaxResult.ok().data(result); return AjaxResult.ok().data(result);
} else { } else {
StpUtil.logout(); StpUtil.logout();

View File

@ -15,6 +15,7 @@ import com.ydool.common.base.BaseService;
import com.ydool.common.cache.ConfigCache; import com.ydool.common.cache.ConfigCache;
import com.ydool.common.data.dto.AjaxResult; import com.ydool.common.data.dto.AjaxResult;
import com.ydool.common.utils.CodecUtils; import com.ydool.common.utils.CodecUtils;
import com.ydool.common.utils.LoginNameUtil;
import com.ydool.common.utils.PasswordUtil; import com.ydool.common.utils.PasswordUtil;
import com.ydool.common.utils.TreeMapUtil; import com.ydool.common.utils.TreeMapUtil;
import com.ydool.system.entity.Menu; import com.ydool.system.entity.Menu;
@ -62,14 +63,12 @@ public class UserServiceImpl extends BaseService<UserMapper, User> implements IU
String message = checkUser("", userRequest); String message = checkUser("", userRequest);
if (StrUtil.isNotBlank(message)) return AjaxResult.fail(message); if (StrUtil.isNotBlank(message)) return AjaxResult.fail(message);
User user = BeanUtil.copyProperties(userRequest, User.class); User user = BeanUtil.copyProperties(userRequest, User.class);
user.setPhone(CodecUtils.encrypt(user.getPhone())); user.setPhone(CodecUtils.encrypt(user.getPhone()));
String initPassword = ConfigCache.getStr(ConfigCache.USER_INIT_PASSWORD, "Siwhnd!@Lc2349#!Rdisabled");
String initPassword = ConfigCache.getStr(ConfigCache.USER_INIT_PASSWORD, "888888"); PasswordUtil.valid(initPassword);
user.setSalt(RandomUtil.randomString(6)); user.setSalt(RandomUtil.randomString(6));
user.setPassword(PasswordUtil.password(user.getSalt(), initPassword)); user.setPassword(PasswordUtil.password(user.getSalt(), initPassword));
user.setLastUpdatePwd(LocalDateTime.now()); user.setLastUpdatePwd(LocalDateTime.now());
boolean flag = save(user); boolean flag = save(user);
return flag ? AjaxResult.ok().msg("保存成功") : AjaxResult.fail("保存失败"); return flag ? AjaxResult.ok().msg("保存成功") : AjaxResult.fail("保存失败");
} }
@ -191,7 +190,8 @@ public class UserServiceImpl extends BaseService<UserMapper, User> implements IU
User user = getById(id); User user = getById(id);
if (ObjectUtil.isNull(user)) return AjaxResult.fail("该用户不存在"); if (ObjectUtil.isNull(user)) return AjaxResult.fail("该用户不存在");
String initPassword = ConfigCache.getStr(ConfigCache.USER_INIT_PASSWORD, "888888"); String initPassword = ConfigCache.getStr(ConfigCache.USER_INIT_PASSWORD, "Siwhnd!@Lc2349#!Rdisabled");
PasswordUtil.valid(initPassword);
user.setSalt(RandomUtil.randomString(6)); user.setSalt(RandomUtil.randomString(6));
user.setPassword(PasswordUtil.password(user.getSalt(), initPassword)); user.setPassword(PasswordUtil.password(user.getSalt(), initPassword));
user.setLastUpdatePwd(LocalDateTime.now()); user.setLastUpdatePwd(LocalDateTime.now());
@ -449,6 +449,7 @@ public class UserServiceImpl extends BaseService<UserMapper, User> implements IU
); );
if (ObjectUtil.isNotNull(user)) return "登录账号不能重复"; if (ObjectUtil.isNotNull(user)) return "登录账号不能重复";
LoginNameUtil.valid(userRequest.getLoginName());
return null; return null;
} }
} }

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" dynamicConfig="false">
<diskStore path="java.io.tmpdir"/>
<!-- 缓存半小时 -->
<cache name="sys_default"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<cache name="sys_user"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存24小时 -->
<cache name="sys_dict"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="864000"
timeToLiveSeconds="864000"
overflowToDisk="false"
diskPersistent="false"/>
<cache name="upms_config"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="864000"
timeToLiveSeconds="864000"
overflowToDisk="false"
diskPersistent="false"/>
<cache name="sys_street"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="864000"
timeToLiveSeconds="864000"
overflowToDisk="false"
diskPersistent="false"/>
<cache name="sys_area"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="864000"
timeToLiveSeconds="864000"
overflowToDisk="false"
diskPersistent="false"/>
<cache name="sys_msg"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="864000"
timeToLiveSeconds="864000"
overflowToDisk="false"
diskPersistent="false"/>
<!-- Token缓存二十四小时 -->
<cache name="sys_login_token"
maxElementsInMemory="1"
maxEntriesLocalHeap="0"
eternal="false"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="false">
</cache>
<!-- 注册手机验证码,缓存十分钟 -->
<cache name="sys_phone_code_register"
maxElementsInMemory="1"
maxEntriesLocalHeap="0"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
overflowToDisk="false">
</cache>
<!-- 登录手机验证码,缓存十分钟 -->
<cache name="sys_phone_code_login"
maxElementsInMemory="1"
maxEntriesLocalHeap="0"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
overflowToDisk="false">
</cache>
<!-- 前端用户修改手机号,手机验证码,缓存十分钟 -->
<cache name="sys_phone_code_user"
maxElementsInMemory="1"
maxEntriesLocalHeap="0"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
overflowToDisk="false">
</cache>
</ehcache>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志格式 -->
<property name="LOG_PATTERN" value="%(%-12(%d{yyyy-MM-dd HH:mm:ss.SSS})) [%level] [%thread] %(%msg%n)"/>
<!-- 文件路径 -->
<property name="LOG_PATH_ERROR" value="./log/error/"/>
<property name="LOG_PATH_INFO" value="./log/info/"/>
<appender name="APPENDER_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="APPENDER_LOG_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH_INFO}/%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_PATTERN}</pattern>
</layout>
</appender>
<appender name="APPENDER_LOG_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH_ERROR}/%d{yyyy-MM-dd}.log</fileNamePattern>
<MaxHistory>90</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${LOG_PATTERN}</pattern>
</layout>
</appender>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL如果设置为WARN则低于WARN的信息都不会输出-->
<root level="INFO">
<appender-ref ref="APPENDER_CONSOLE"/> <!--debug-->
<appender-ref ref="APPENDER_LOG_INFO"/><!--info-->
<appender-ref ref="APPENDER_LOG_ERROR"/><!--error-->
</root>
</configuration>