重写用户快速登录逻辑
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
package cn.iocoder.mall.system.biz.dao.oauth2;
|
||||
|
||||
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2MobileCodeDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface OAuth2MobileCodeMapper extends BaseMapper<OAuth2MobileCodeDO> {
|
||||
|
||||
/**
|
||||
* 获得手机号的最后一个手机验证码
|
||||
*
|
||||
* @param mobile 手机号
|
||||
* @return 手机验证码
|
||||
*/
|
||||
default OAuth2MobileCodeDO selectLastByMobile(String mobile) {
|
||||
QueryWrapper<OAuth2MobileCodeDO> query = new QueryWrapper<OAuth2MobileCodeDO>()
|
||||
.eq("mobile", mobile)
|
||||
.orderByDesc("id")
|
||||
.last("limit 1");
|
||||
return selectOne(query);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
package cn.iocoder.mall.system.biz.dao.user;
|
||||
|
||||
import cn.iocoder.mall.mybatis.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
|
||||
import cn.iocoder.mall.system.biz.dataobject.user.UserDO;
|
||||
import cn.iocoder.mall.system.biz.dto.user.UserPageDTO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -15,12 +12,6 @@ import org.springframework.stereotype.Repository;
|
||||
@Repository
|
||||
public interface UserMapper extends BaseMapper<UserDO> {
|
||||
|
||||
default UserDO selectByAccountId(Integer accountId) {
|
||||
return selectOne(new QueryWrapper<UserDO>()
|
||||
.eq("account_id", accountId)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件分页查询用户列表
|
||||
* @param userPageDTO
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package cn.iocoder.mall.system.biz.dataobject.oauth2;
|
||||
|
||||
import cn.iocoder.mall.mybatis.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* OAuth2 手机验证码
|
||||
*/
|
||||
@TableName("oauth2_mobile_code")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2MobileCodeDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 创建 IP
|
||||
*/
|
||||
private String createIp;
|
||||
/**
|
||||
* 今日发送的第几条
|
||||
*/
|
||||
private Integer todayIndex;
|
||||
/**
|
||||
* 是否使用
|
||||
*/
|
||||
private Boolean used;
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date usedTime;
|
||||
/**
|
||||
* 使用 IP
|
||||
*/
|
||||
private Date usedIp;
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.common.framework.util.HttpUtil;
|
||||
import cn.iocoder.common.framework.util.MallUtil;
|
||||
import cn.iocoder.common.framework.util.MallUtils;
|
||||
import cn.iocoder.mall.system.biz.log.operation.annotation.OperationLogging;
|
||||
import cn.iocoder.mall.system.biz.log.operation.enums.LogStatus;
|
||||
import cn.iocoder.mall.system.biz.log.operation.event.OperationLogEvent;
|
||||
@@ -98,7 +98,7 @@ public class OperationLogAspect {
|
||||
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
|
||||
return new OperationLogDTO()
|
||||
.setTraceId(MallUtil.getTraceId())
|
||||
.setTraceId(MallUtils.getTraceId())
|
||||
.setUri(URLUtil.getPath(request.getRequestURI()))
|
||||
.setUserAgent(HttpUtil.getUserAgent(request))
|
||||
.setIp(HttpUtil.getIp(request))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.iocoder.mall.system.biz.service.authorization;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.mybatis.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
||||
@@ -127,7 +127,7 @@ public class RoleServiceImpl implements RoleService {
|
||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NAME_DUPLICATE, name);
|
||||
}
|
||||
// 2. 是否存在相同编码的角色
|
||||
if (!StringUtil.hasText(code)) {
|
||||
if (!StringUtils.hasText(code)) {
|
||||
return;
|
||||
}
|
||||
// 该 code 编码被其它角色所使用
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package cn.iocoder.mall.system.biz.service.oauth2;
|
||||
|
||||
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeSendDTO;
|
||||
|
||||
/**
|
||||
* OAuth2 手机验证码 Service 接口
|
||||
*
|
||||
* 我们将手机验证码登陆的方式,作为一种拓展的 OAuth2 的认证方式。因此,我们放在了 `oauth2` 包下
|
||||
*/
|
||||
public interface OAuth2MobileCodeService {
|
||||
|
||||
void send(OAuth2MobileCodeSendDTO sendDTO);
|
||||
|
||||
void use(String mobile, String code);
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package cn.iocoder.mall.system.biz.service.oauth2;
|
||||
|
||||
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.ValidationUtil;
|
||||
import cn.iocoder.mall.system.biz.dao.oauth2.OAuth2MobileCodeMapper;
|
||||
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2MobileCodeDO;
|
||||
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeSendDTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum.*;
|
||||
|
||||
@Service
|
||||
public class OAuth2MobileCodeServiceImpl implements OAuth2MobileCodeService {
|
||||
|
||||
/**
|
||||
* 每条验证码的过期时间,单位:毫秒
|
||||
*/
|
||||
@Value("${modules.oauth2-mobile-code-service.code-expire-time-millis}")
|
||||
private int codeExpireTimes;
|
||||
/**
|
||||
* 每日发送最大数量
|
||||
*/
|
||||
@Value("${modules.oauth2-mobile-code-service.send-maximum-quantity-per-day}")
|
||||
private int sendMaximumQuantityPerDay;
|
||||
/**
|
||||
* 短信发送频率,单位:毫秒
|
||||
*/
|
||||
@Value("${modules.oauth2-mobile-code-service.send-frequency}")
|
||||
private int sendFrequency;
|
||||
|
||||
@Autowired
|
||||
private OAuth2MobileCodeMapper oauth2MobileCodeMapper;
|
||||
|
||||
@Override
|
||||
public void send(OAuth2MobileCodeSendDTO sendDTO) {
|
||||
if (!ValidationUtil.isMobile(sendDTO.getMobile())) {
|
||||
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "手机格式不正确"); // TODO 有点搓
|
||||
}
|
||||
// 校验是否可以发送验证码
|
||||
OAuth2MobileCodeDO lastMobileCodePO = oauth2MobileCodeMapper.selectLastByMobile(sendDTO.getMobile());
|
||||
if (lastMobileCodePO != null) {
|
||||
if (lastMobileCodePO.getTodayIndex() >= sendMaximumQuantityPerDay) { // 超过当天发送的上限。
|
||||
throw ServiceExceptionUtil.exception(OAUTH2_MOBILE_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
|
||||
}
|
||||
if (System.currentTimeMillis() - lastMobileCodePO.getCreateTime().getTime() < sendFrequency) { // 发送过于频繁
|
||||
throw ServiceExceptionUtil.exception(OAUTH2_MOBILE_CODE_SEND_TOO_FAST);
|
||||
}
|
||||
// TODO 提升,每个 IP 每天可发送数量
|
||||
// TODO 提升,每个 IP 每小时可发送数量
|
||||
}
|
||||
// 创建验证码记录
|
||||
OAuth2MobileCodeDO newMobileCodePO = new OAuth2MobileCodeDO().setMobile(sendDTO.getMobile())
|
||||
.setCode("9999") // TODO 芋艿,随机 4 位验证码 or 6 位验证码
|
||||
.setTodayIndex(lastMobileCodePO != null ? lastMobileCodePO.getTodayIndex() : 1)
|
||||
.setCreateIp(sendDTO.getIp())
|
||||
.setUsed(false);
|
||||
newMobileCodePO.setCreateTime(new Date());
|
||||
oauth2MobileCodeMapper.insert(newMobileCodePO);
|
||||
// TODO 发送验证码短信
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(String mobile, String code) {
|
||||
// 校验验证码
|
||||
OAuth2MobileCodeDO mobileCodeDO = oauth2MobileCodeMapper.selectLastByMobile(mobile);
|
||||
if (mobileCodeDO == null) { // 若验证码不存在,抛出异常
|
||||
throw ServiceExceptionUtil.exception(OAUTH2_MOBILE_CODE_NOT_FOUND);
|
||||
}
|
||||
if (System.currentTimeMillis() - mobileCodeDO.getCreateTime().getTime() >= codeExpireTimes) { // 验证码已过期
|
||||
throw ServiceExceptionUtil.exception(OAUTH2_MOBILE_CODE_EXPIRED);
|
||||
}
|
||||
if (mobileCodeDO.getUsed()) { // 验证码已使用
|
||||
throw ServiceExceptionUtil.exception(OAUTH2_MOBILE_CODE_USED);
|
||||
}
|
||||
if (!mobileCodeDO.getCode().equals(code)) {
|
||||
throw ServiceExceptionUtil.exception(OAUTH2_MOBILE_CODE_NOT_CORRECT);
|
||||
}
|
||||
// 使用验证码
|
||||
OAuth2MobileCodeDO update = new OAuth2MobileCodeDO().setId(mobileCodeDO.getId())
|
||||
.setUsed(true).setUsedTime(new Date()); // TODO usedIp
|
||||
oauth2MobileCodeMapper.updateById(update);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +1,14 @@
|
||||
package cn.iocoder.mall.system.rest.controller.oauth2;
|
||||
|
||||
import cn.iocoder.common.framework.constant.MallConstants;
|
||||
import cn.iocoder.common.framework.util.HttpUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.security.core.annotation.RequiresNone;
|
||||
import cn.iocoder.mall.system.biz.bo.user.UserAuthenticateBO;
|
||||
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeAuthenticateDTO;
|
||||
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeSendDTO;
|
||||
import cn.iocoder.mall.system.biz.service.oauth2.OAuth2MobileCodeService;
|
||||
import cn.iocoder.mall.system.biz.service.oauth2.OAuth2Service;
|
||||
import cn.iocoder.mall.system.biz.service.user.UserService;
|
||||
import cn.iocoder.mall.system.rest.convert.oauth2.UsersOAuth2Convert;
|
||||
import cn.iocoder.mall.system.rest.request.oauth2.UsersOAuth2MobileCodeAuthenticateRequest;
|
||||
import cn.iocoder.mall.system.rest.response.user.UsersOAuth2AuthenticateResponse;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(MallConstants.ROOT_PATH_USER + "/oauth2")
|
||||
@Api(tags = "用户 - OAuth2 API")
|
||||
@@ -36,33 +21,6 @@ public class UsersOAuth2Controller {
|
||||
@Autowired
|
||||
private OAuth2MobileCodeService oauth2MobileCodeService;
|
||||
|
||||
@PostMapping("/mobile-code-authenticate")
|
||||
@ApiOperation("手机验证码认证")
|
||||
@RequiresNone
|
||||
public CommonResult<UsersOAuth2AuthenticateResponse> mobileCodeAuthenticate(UsersOAuth2MobileCodeAuthenticateRequest request,
|
||||
HttpServletRequest httpRequest) {
|
||||
// 执行认证
|
||||
OAuth2MobileCodeAuthenticateDTO authenticateDTO = UsersOAuth2Convert.INSTANCE.convert(request)
|
||||
.setIp(HttpUtil.getIp(httpRequest));
|
||||
UserAuthenticateBO userAuthenticateBO = userService.authenticate(authenticateDTO);
|
||||
// 转换返回
|
||||
return CommonResult.success(
|
||||
UsersOAuth2Convert.INSTANCE.convert(userAuthenticateBO)
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("/send-mobile-code")
|
||||
@ApiOperation("发送手机验证码")
|
||||
@ApiImplicitParam(name = "mobile", value = "手机号", required = true, example = "15601691234")
|
||||
@RequiresNone
|
||||
public CommonResult<Boolean> sendMobileCode(@RequestParam("mobile") String mobile,
|
||||
HttpServletRequest request) {
|
||||
// 执行发送验证码
|
||||
OAuth2MobileCodeSendDTO sendDTO = new OAuth2MobileCodeSendDTO()
|
||||
.setMobile(mobile).setIp(HttpUtil.getIp(request));
|
||||
oauth2MobileCodeService.send(sendDTO);
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user