Introducing new features. 完善安全校验,注册、修改手机号 均需要手机号验证码

This commit is contained in:
lengleng 2022-09-23 23:53:21 +08:00
parent 8cfa9c75be
commit 15c0949ea7
12 changed files with 71 additions and 31 deletions

View File

@ -38,7 +38,7 @@
| 依赖 | 版本 | | 依赖 | 版本 |
| ---------------------- |------------| | ---------------------- |------------|
| Spring Boot | 2.7.3 | | Spring Boot | 2.7.4 |
| Spring Cloud | 2021.0.4 | | Spring Cloud | 2021.0.4 |
| Spring Cloud Alibaba | 2021.0.4.0 | | Spring Cloud Alibaba | 2021.0.4.0 |
| Spring Authorization Server | 0.3.1 | | Spring Authorization Server | 0.3.1 |

View File

@ -115,7 +115,7 @@ public interface SecurityConstants {
/** /**
* 短信登录 参数名称 * 短信登录 参数名称
*/ */
String SMS_PARAMETER_NAME = "mobile"; String SMS_PARAMETER_NAME = "phone";
/** /**
* 授权码模式confirm * 授权码模式confirm

View File

@ -88,6 +88,11 @@ public interface ErrorCodes {
*/ */
String SYS_APP_SMS_OFTEN = "sys.app.sms.often"; String SYS_APP_SMS_OFTEN = "sys.app.sms.often";
/**
* 验证码错误
*/
String SYS_APP_SMS_ERROR = "sys.app.sms.error";
/** /**
* 手机号未注册 * 手机号未注册
*/ */

View File

@ -18,6 +18,7 @@ sys.param.config.error={0} \u7CFB\u7EDF\u53C2\u6570\u914D\u7F6E\u9519\u8BEF
sys.menu.delete.existing=\u83DC\u5355\u542B\u6709\u4E0B\u7EA7\u4E0D\u80FD\u5220\u9664 sys.menu.delete.existing=\u83DC\u5355\u542B\u6709\u4E0B\u7EA7\u4E0D\u80FD\u5220\u9664
sys.app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41 sys.app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41
sys.app.sms.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
sys.app.phone.unregistered={0} \u624B\u673A\u53F7\u672A\u6CE8\u518C sys.app.phone.unregistered={0} \u624B\u673A\u53F7\u672A\u6CE8\u518C
sys.dict.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u5220\u9664 sys.dict.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u5220\u9664

View File

@ -115,18 +115,18 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory<Obje
String randomStr = request.getQueryParams().getFirst("randomStr"); String randomStr = request.getQueryParams().getFirst("randomStr");
if (CharSequenceUtil.isBlank(randomStr)) { if (CharSequenceUtil.isBlank(randomStr)) {
randomStr = request.getQueryParams().getFirst("mobile"); randomStr = request.getQueryParams().getFirst(SecurityConstants.SMS_PARAMETER_NAME);
} }
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr; String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
Object codeObj = redisTemplate.opsForValue().get(key); Object codeObj = redisTemplate.opsForValue().get(key);
redisTemplate.delete(key);
if (ObjectUtil.isEmpty(codeObj) || !code.equals(codeObj)) { if (ObjectUtil.isEmpty(codeObj) || !code.equals(codeObj)) {
throw new ValidateCodeException("验证码不合法"); throw new ValidateCodeException("验证码不合法");
} }
redisTemplate.delete(key);
} }
} }

View File

@ -47,4 +47,9 @@ public class UserDTO extends SysUser {
*/ */
private String newpassword1; private String newpassword1;
/**
* 验证码
*/
private String code;
} }

View File

@ -156,7 +156,7 @@ public class UserController {
} }
/** /**
* 更新用户信息 * 管理员更新用户信息
* @param userDto 用户信息 * @param userDto 用户信息
* @return R * @return R
*/ */
@ -164,7 +164,7 @@ public class UserController {
@PutMapping @PutMapping
@PreAuthorize("@pms.hasPermission('sys_user_edit')") @PreAuthorize("@pms.hasPermission('sys_user_edit')")
public R<Boolean> updateUser(@Valid @RequestBody UserDTO userDto) { public R<Boolean> updateUser(@Valid @RequestBody UserDTO userDto) {
return R.ok(userService.updateUser(userDto)); return userService.updateUser(userDto);
} }
/** /**
@ -179,7 +179,7 @@ public class UserController {
} }
/** /**
* 修改个人信息 * 个人修改个人信息
* @param userDto userDto * @param userDto userDto
* @return success/false * @return success/false
*/ */
@ -187,7 +187,7 @@ public class UserController {
@PutMapping("/edit") @PutMapping("/edit")
public R<Boolean> updateUserInfo(@Valid @RequestBody UserDTO userDto) { public R<Boolean> updateUserInfo(@Valid @RequestBody UserDTO userDto) {
userDto.setUsername(SecurityUtils.getUser().getUsername()); userDto.setUsername(SecurityUtils.getUser().getUsername());
return R.ok(userService.updateUserInfo(userDto)); return userService.updateUserInfo(userDto);
} }
/** /**

View File

@ -27,9 +27,17 @@ public interface AppService {
/** /**
* 发送手机验证码 * 发送手机验证码
* @param mobile mobile * @param phone phone
* @return code * @return code
*/ */
R<Boolean> sendSmsCode(String mobile); R<Boolean> sendSmsCode(String phone);
/**
* 校验验证码
* @param phone 手机号
* @param code 验证码
* @return
*/
boolean check(String phone, String code);
} }

View File

@ -63,14 +63,14 @@ public interface SysUserService extends IService<SysUser> {
* @param userDto 用户信息 * @param userDto 用户信息
* @return Boolean 操作成功返回true,操作失败返回false * @return Boolean 操作成功返回true,操作失败返回false
*/ */
Boolean updateUserInfo(UserDTO userDto); R<Boolean> updateUserInfo(UserDTO userDto);
/** /**
* 更新指定用户信息 * 更新指定用户信息
* @param userDto 用户信息 * @param userDto 用户信息
* @return * @return
*/ */
Boolean updateUser(UserDTO userDto); R<Boolean> updateUser(UserDTO userDto);
/** /**
* 通过ID查询用户信息 * 通过ID查询用户信息

View File

@ -17,10 +17,7 @@
package com.pig4cloud.pig.admin.service.impl; package com.pig4cloud.pig.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.mapper.SysUserMapper; import com.pig4cloud.pig.admin.mapper.SysUserMapper;
import com.pig4cloud.pig.admin.service.AppService; import com.pig4cloud.pig.admin.service.AppService;
import com.pig4cloud.pig.common.core.constant.CacheConstants; import com.pig4cloud.pig.common.core.constant.CacheConstants;
@ -34,7 +31,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@ -61,13 +58,6 @@ public class AppServiceImpl implements AppService {
*/ */
@Override @Override
public R<Boolean> sendSmsCode(String phone) { public R<Boolean> sendSmsCode(String phone) {
List<SysUser> userList = userMapper.selectList(Wrappers.<SysUser>query().lambda().eq(SysUser::getPhone, phone));
if (CollUtil.isEmpty(userList)) {
log.info("手机号未注册:{}", phone);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, phone));
}
Object codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + phone); Object codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + phone);
if (codeObj != null) { if (codeObj != null) {
@ -85,4 +75,20 @@ public class AppServiceImpl implements AppService {
return R.ok(Boolean.TRUE, code); return R.ok(Boolean.TRUE, code);
} }
/**
* 校验验证码
* @param phone 手机号
* @param code 验证码
* @return
*/
@Override
public boolean check(String phone, String code) {
Object codeObj = redisTemplate.opsForValue().get(CacheConstants.DEFAULT_CODE_KEY + phone);
if (Objects.isNull(codeObj)) {
return false;
}
return codeObj.equals(code);
}
} }

View File

@ -30,6 +30,7 @@ import com.pig4cloud.pig.admin.api.util.ParamResolver;
import com.pig4cloud.pig.admin.api.vo.UserExcelVO; import com.pig4cloud.pig.admin.api.vo.UserExcelVO;
import com.pig4cloud.pig.admin.api.vo.UserVO; import com.pig4cloud.pig.admin.api.vo.UserVO;
import com.pig4cloud.pig.admin.mapper.*; import com.pig4cloud.pig.admin.mapper.*;
import com.pig4cloud.pig.admin.service.AppService;
import com.pig4cloud.pig.admin.service.SysMenuService; import com.pig4cloud.pig.admin.service.SysMenuService;
import com.pig4cloud.pig.admin.service.SysUserService; import com.pig4cloud.pig.admin.service.SysUserService;
import com.pig4cloud.pig.common.core.constant.CacheConstants; import com.pig4cloud.pig.common.core.constant.CacheConstants;
@ -65,6 +66,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder(); private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private final AppService appService;
private final SysRoleMapper sysRoleMapper; private final SysRoleMapper sysRoleMapper;
private final SysDeptMapper sysDeptMapper; private final SysDeptMapper sysDeptMapper;
@ -171,26 +174,33 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Override @Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUserInfo(UserDTO userDto) { public R<Boolean> updateUserInfo(UserDTO userDto) {
UserVO userVO = baseMapper.getUserVoByUsername(userDto.getUsername()); UserVO userVO = baseMapper.getUserVoByUsername(userDto.getUsername());
Assert.isTrue(ENCODER.matches(userDto.getPassword(), userVO.getPassword()), // 判断手机号是否修改,更新手机号校验验证码
MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR)); if (!StrUtil.equals(userVO.getPhone(), userDto.getPhone())) {
if (!appService.check(userDto.getPhone(), userDto.getCode())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_ERROR));
}
}
// 修改密码逻辑
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
if (StrUtil.isNotBlank(userDto.getNewpassword1())) { if (StrUtil.isNotBlank(userDto.getNewpassword1())) {
Assert.isTrue(ENCODER.matches(userDto.getPassword(), userVO.getPassword()),
MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
sysUser.setPassword(ENCODER.encode(userDto.getNewpassword1())); sysUser.setPassword(ENCODER.encode(userDto.getNewpassword1()));
} }
sysUser.setPhone(userDto.getPhone()); sysUser.setPhone(userDto.getPhone());
sysUser.setUserId(userVO.getUserId()); sysUser.setUserId(userVO.getUserId());
sysUser.setAvatar(userDto.getAvatar()); sysUser.setAvatar(userDto.getAvatar());
return this.updateById(sysUser); return R.ok(this.updateById(sysUser));
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUser(UserDTO userDto) { public R<Boolean> updateUser(UserDTO userDto) {
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser); BeanUtils.copyProperties(userDto, sysUser);
sysUser.setUpdateTime(LocalDateTime.now()); sysUser.setUpdateTime(LocalDateTime.now());
@ -215,7 +225,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
userPost.setPostId(postId); userPost.setPostId(postId);
userPost.insert(); userPost.insert();
}); });
return Boolean.TRUE; return R.ok();
} }
/** /**
@ -366,6 +376,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
*/ */
@Override @Override
public R<Boolean> registerUser(UserDTO userDto) { public R<Boolean> registerUser(UserDTO userDto) {
// 校验验证码
if (!appService.check(userDto.getPhone(), userDto.getCode())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_ERROR));
}
// 判断用户名是否存在 // 判断用户名是否存在
SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername())); SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
if (sysUser != null) { if (sysUser != null) {

View File

@ -27,7 +27,7 @@
<url>https://www.pig4cloud.com</url> <url>https://www.pig4cloud.com</url>
<properties> <properties>
<spring-boot.version>2.7.3</spring-boot.version> <spring-boot.version>2.7.4</spring-boot.version>
<spring-cloud.version>2021.0.4</spring-cloud.version> <spring-cloud.version>2021.0.4</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>