用户登录问题修改
This commit is contained in:
parent
5c340f728c
commit
e0b41291b3
|
|
@ -0,0 +1,34 @@
|
|||
package com.bonus.auth.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
|
||||
public enum VerificationCodeType {
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
LOGIN,
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
REGISTER;
|
||||
|
||||
@JsonCreator
|
||||
public static VerificationCodeType fromString(String key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 自定义转换逻辑,允许大小写不敏感的匹配
|
||||
for (VerificationCodeType type : VerificationCodeType.values()) {
|
||||
if (type.name().equalsIgnoreCase(key)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
// throw new ServiceException("不支持的登录方式");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.bonus.auth.controller;
|
||||
|
||||
import com.bonus.auth.config.LoginType;
|
||||
import com.bonus.auth.factory.LoginStrategyFactory;
|
||||
import com.bonus.auth.form.LoginBody;
|
||||
import com.bonus.auth.form.RegisterBody;
|
||||
|
|
@ -78,7 +77,7 @@ public class TokenController {
|
|||
passwordService.validate(user, form.getPassword(), System.currentTimeMillis());
|
||||
// 处理IP校验
|
||||
passwordValidatorService.handleIpValidation(form.getUsername(), user);
|
||||
if (userResult == null || userResult.getData() == null || R.FAIL == userResult.getCode()) {
|
||||
if (userResult.getData() == null || R.FAIL == userResult.getCode()) {
|
||||
return R.fail("登录用户不存在");
|
||||
}
|
||||
Set<String> roles = userResult.getData().getRoles();
|
||||
|
|
@ -97,19 +96,13 @@ public class TokenController {
|
|||
|
||||
@PostMapping("login")
|
||||
public R<?> login(@RequestBody LoginBody form) {
|
||||
|
||||
// 获取相应的登录策略
|
||||
LoginStrategy strategy = loginStrategyFactory.getStrategy(form.getLoginType());
|
||||
if (strategy == null) {
|
||||
return R.fail("不支持的登录方式");
|
||||
}
|
||||
LoginUser login = strategy.login(form.getUsername(), form.getPassword());
|
||||
if (login.getRoles().contains("admin") && form.getLoginType().equals(LoginType.USERNAME_PASSWORD) && isAdmin) {
|
||||
passwordValidatorService.checkPhoneCaptcha(form.getVerificationCode(), login.getSysUser().getPhonenumber());
|
||||
return R.ok(tokenService.createToken(login));
|
||||
} else {
|
||||
return R.ok(tokenService.createToken(login));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +114,7 @@ public class TokenController {
|
|||
*/
|
||||
@PostMapping("getPhoneCode")
|
||||
public R<?> getPhoneCode(@RequestBody LoginBody form) {
|
||||
return sysLoginService.getPhoneCode(form.getMobile(), form.getMobileCodeType());
|
||||
return sysLoginService.getPhoneCode(form.getUsername(), form.getVerificationCodeType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package com.bonus.auth.factory;
|
||||
|
||||
import com.bonus.auth.config.VerificationCodeType;
|
||||
import com.bonus.auth.service.LoginVerificationCodeSender;
|
||||
import com.bonus.auth.service.RegisterVerificationCodeSender;
|
||||
import com.bonus.auth.service.VerificationCodeStrategy;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
@Component
|
||||
public class VerificationCodeStrategyFactory {
|
||||
private final Map<VerificationCodeType, VerificationCodeStrategy> strategyMap;
|
||||
|
||||
@Autowired
|
||||
public VerificationCodeStrategyFactory(List<VerificationCodeStrategy> strategies) {
|
||||
strategyMap = new HashMap<>();
|
||||
// 通过类型查找对应的策略
|
||||
strategies.forEach(strategy -> {
|
||||
if (strategy instanceof LoginVerificationCodeSender) {
|
||||
strategyMap.put(VerificationCodeType.LOGIN, strategy);
|
||||
} else if (strategy instanceof RegisterVerificationCodeSender) {
|
||||
strategyMap.put(VerificationCodeType.REGISTER, strategy);
|
||||
}
|
||||
// 继续添加其他策略
|
||||
});
|
||||
}
|
||||
|
||||
public VerificationCodeStrategy getStrategy(VerificationCodeType verificationCodeType) {
|
||||
return strategyMap.get(verificationCodeType);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.bonus.auth.form;
|
||||
|
||||
import com.bonus.auth.config.LoginType;
|
||||
import com.bonus.auth.config.VerificationCodeType;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
|
|
@ -33,6 +34,8 @@ public class LoginBody {
|
|||
|
||||
private LoginType loginType;
|
||||
|
||||
private VerificationCodeType verificationCodeType;
|
||||
|
||||
private String mobileCodeType;
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package com.bonus.auth.service;
|
||||
|
||||
import com.bonus.common.core.constant.CacheConstants;
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.utils.VerificationCodeUtils;
|
||||
import com.bonus.common.redis.service.RedisService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class EmailService {
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
@Autowired
|
||||
private JavaMailSender mailSender; // 自动注入JavaMailSender,用于发送邮件
|
||||
|
||||
/**
|
||||
* 发送简单邮件
|
||||
*
|
||||
* @param to 接收者邮箱地址
|
||||
*/
|
||||
public R<Object> sendSimpleEmail(String to) {
|
||||
// 创建一个简单邮件消息对象
|
||||
String code = VerificationCodeUtils.generateVerificationCode(VerificationCodeUtils.CodeType.NUMERIC);
|
||||
String str = "您的验证码为" + code + ",尊敬的客户,以上验证码3分钟有效,微服务平台提醒您:转发可能导致账号被盗,请勿将验证码泄露于他人";
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
// 发件人邮箱地址
|
||||
message.setFrom("2642480752@qq.com");
|
||||
// 收件人邮箱地址
|
||||
message.setTo(to);
|
||||
// 邮件主题
|
||||
message.setSubject("【博诺思】");
|
||||
// 邮件内容
|
||||
message.setText(str);
|
||||
// 发送邮件
|
||||
mailSender.send(message);
|
||||
String verifyKey = CacheConstants.CAPTCHA_PHONE_CODE_KEY + to;
|
||||
redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package com.bonus.auth.service;
|
||||
|
||||
import com.bonus.common.core.constant.SecurityConstants;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.security.service.EmailService;
|
||||
import com.bonus.common.security.service.SmsService;
|
||||
import com.bonus.system.api.RemoteUserService;
|
||||
import com.bonus.system.api.model.LoginUser;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 验证码发送服务
|
||||
* 可发送到邮箱或手机
|
||||
*
|
||||
* @author bonus
|
||||
*/
|
||||
@Service
|
||||
public class LoginVerificationCodeSender implements VerificationCodeStrategy {
|
||||
|
||||
private static final String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
|
||||
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
|
||||
|
||||
@Resource
|
||||
private EmailService emailService;
|
||||
|
||||
@Resource
|
||||
private SmsService smsService;
|
||||
|
||||
@Resource
|
||||
private RemoteUserService remoteUserService;
|
||||
|
||||
/**
|
||||
* 发送验证码到邮箱或手机
|
||||
*
|
||||
* @param contactInfo 可以是邮箱地址或手机号码
|
||||
* @return 验证码发送的结果
|
||||
*/
|
||||
@Override
|
||||
public String sendVerificationCode(String contactInfo) {
|
||||
if (isEmail(contactInfo)) {
|
||||
return emailService.sendSimpleEmail(contactInfo);
|
||||
} else if (isPhone(contactInfo)) {
|
||||
return smsService.sendSimplePhone(contactInfo);
|
||||
} else {
|
||||
return handleUsernameLogin(contactInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是邮箱
|
||||
*
|
||||
* @param contactInfo 输入信息
|
||||
* @return 是否为邮箱
|
||||
*/
|
||||
private boolean isEmail(String contactInfo) {
|
||||
return contactInfo.matches(EMAIL_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是手机号
|
||||
*
|
||||
* @param contactInfo 输入信息
|
||||
* @return 是否为手机号
|
||||
*/
|
||||
private boolean isPhone(String contactInfo) {
|
||||
return contactInfo.matches(PHONE_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理用户名登录逻辑
|
||||
*
|
||||
* @param username 用户名
|
||||
* @return 验证码发送的结果
|
||||
*/
|
||||
private String handleUsernameLogin(String username) {
|
||||
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
|
||||
if (userResult == null || userResult.getData() == null || R.FAIL == userResult.getCode()) {
|
||||
throw new ServiceException("用户名/密码错误");
|
||||
}
|
||||
LoginUser user = userResult.getData();
|
||||
// 如果用户是管理员,则发送手机验证码
|
||||
if (user.getRoles().contains("admin")) {
|
||||
if (StringUtils.isEmpty(user.getSysUser().getPhonenumber())) {
|
||||
throw new ServiceException("此账号未绑定手机号,请先绑定手机号");
|
||||
}
|
||||
return smsService.sendSimplePhone(user.getSysUser().getPhonenumber());
|
||||
} else {
|
||||
throw new ServiceException("不支持的登录方式");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -236,7 +236,7 @@ public class PasswordValidatorService {
|
|||
if (StringUtils.isEmpty(phone)) {
|
||||
throw new CaptchaException("手机号不能为空");
|
||||
}
|
||||
String verifyKey = CacheConstants.CAPTCHA_PHONE_CODE_KEY + StringUtils.nvl(phone, "");
|
||||
String verifyKey = CacheConstants.VERIFICATION_CODE + StringUtils.nvl(phone, "");
|
||||
String captcha = redisService.getCacheObject(verifyKey);
|
||||
if (captcha == null) {
|
||||
throw new CaptchaException("手机验证码已失效");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package com.bonus.auth.service;
|
||||
|
||||
import com.bonus.common.core.constant.SecurityConstants;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.security.service.EmailService;
|
||||
import com.bonus.common.security.service.SmsService;
|
||||
import com.bonus.system.api.RemoteUserService;
|
||||
import com.bonus.system.api.model.LoginUser;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
@Service
|
||||
public class RegisterVerificationCodeSender implements VerificationCodeStrategy {
|
||||
|
||||
private static final String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
|
||||
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
|
||||
|
||||
@Resource
|
||||
private EmailService emailService;
|
||||
@Resource
|
||||
private SmsService smsService;
|
||||
|
||||
@Resource
|
||||
private RemoteUserService remoteUserService;
|
||||
|
||||
/**
|
||||
* 发送验证码到邮箱或手机
|
||||
*
|
||||
* @param contactInfo 可以是邮箱地址或手机号码
|
||||
* @return 验证码发送的结果
|
||||
*/
|
||||
@Override
|
||||
public String sendVerificationCode(String contactInfo) {
|
||||
R<LoginUser> userResult = remoteUserService.getUserInfo(contactInfo, SecurityConstants.INNER);
|
||||
if (userResult.getData() != null) {
|
||||
throw new ServiceException("联系方式已经注册账号");
|
||||
}
|
||||
if (isEmail(contactInfo)) {
|
||||
return emailService.sendSimpleEmail(contactInfo);
|
||||
} else if (isPhone(contactInfo)) {
|
||||
return smsService.sendSimplePhone(contactInfo);
|
||||
} else {
|
||||
throw new ServiceException("请输入正确的联系方式");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是邮箱
|
||||
*
|
||||
* @param contactInfo 输入信息
|
||||
* @return 是否为邮箱
|
||||
*/
|
||||
private boolean isEmail(String contactInfo) {
|
||||
return contactInfo.matches(EMAIL_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是手机号
|
||||
*
|
||||
* @param contactInfo 输入信息
|
||||
* @return 是否为手机号
|
||||
*/
|
||||
private boolean isPhone(String contactInfo) {
|
||||
return contactInfo.matches(PHONE_REGEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.bonus.auth.service;
|
||||
|
||||
import com.bonus.auth.config.VerificationCodeType;
|
||||
import com.bonus.auth.factory.VerificationCodeStrategyFactory;
|
||||
import com.bonus.auth.form.RegisterBody;
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.constant.SecurityConstants;
|
||||
|
|
@ -8,15 +10,11 @@ import com.bonus.common.core.domain.R;
|
|||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import com.bonus.common.redis.service.RedisService;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
import com.bonus.system.api.RemoteUserService;
|
||||
import com.bonus.system.api.domain.SysUser;
|
||||
import com.bonus.system.api.model.LoginUser;
|
||||
import com.hankcs.hanlp.HanLP;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
|
@ -30,115 +28,31 @@ public class SysLoginService {
|
|||
@Autowired
|
||||
private RemoteUserService remoteUserService;
|
||||
|
||||
@Autowired
|
||||
private SysPasswordService passwordService;
|
||||
|
||||
@Autowired
|
||||
private SysRecordLogService recordLogService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private EmailService emailService;
|
||||
|
||||
@Value("${system.supports.phoneLogin}")
|
||||
private boolean supportsPhoneLogin;
|
||||
|
||||
@Value("${system.supports.emailLogin}")
|
||||
private boolean supportsEmailLogin;
|
||||
|
||||
@Resource
|
||||
private PasswordValidatorService passwordValidatorService;
|
||||
|
||||
@Resource
|
||||
private VerificationCodeStrategyFactory verificationCodeStrategyFactory;
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*
|
||||
* @param username 用户名或手机号
|
||||
* @param getMobileCodeType 获取验证码类型(register:注册,其他:登录)
|
||||
* @param verificationCodeType 获取验证码类型(register:注册,其他:登录)
|
||||
* @return 响应结果
|
||||
*/
|
||||
public R<T> getPhoneCode(String username, String getMobileCodeType) {
|
||||
// 记录开始时间
|
||||
long startTime = System.currentTimeMillis();
|
||||
int contactType = getContactType(username);
|
||||
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
|
||||
boolean userExists = userResult != null && userResult.getData() != null;
|
||||
if (userResult.getData().getRoles().contains("admin")) {
|
||||
passwordService.createPhoneCaptcha(userResult.getData().getSysUser().getPhonenumber());
|
||||
return R.ok();
|
||||
public R<?> getPhoneCode(String username, VerificationCodeType verificationCodeType) {
|
||||
// 获取相应的登录策略
|
||||
VerificationCodeStrategy strategyFactory = verificationCodeStrategyFactory.getStrategy(verificationCodeType);
|
||||
if (strategyFactory == null) {
|
||||
return R.fail("不支持的方式");
|
||||
}
|
||||
if (contactType == 2) {
|
||||
recordLogService.saveLogs(username, startTime, "获取验证码失败", "联系方式无效", null, "失败");
|
||||
throw new ServiceException("请输入正确的联系方式");
|
||||
}
|
||||
if ("register".equals(getMobileCodeType)) {
|
||||
handleRegister(username, startTime, contactType, userExists);
|
||||
} else {
|
||||
handleLogin(username, startTime, contactType, userExists);
|
||||
}
|
||||
return R.ok();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理注册操作
|
||||
*
|
||||
* @param username 用户名或手机号
|
||||
* @param startTime 操作开始时间
|
||||
* @param contactType 联系方式类型(0:邮箱,1:手机号,2:无效)
|
||||
* @param userExists 用户是否存在
|
||||
*/
|
||||
private void handleRegister(String username, long startTime, int contactType, boolean userExists) {
|
||||
if (userExists) {
|
||||
recordLogService.saveLogs(username, startTime, contactType == 0 ? "获取邮箱验证码" : "获取手机验证码",
|
||||
contactType == 0 ? "此邮箱已注册" : "此手机号已注册", null, "失败");
|
||||
throw new ServiceException(contactType == 0 ? "此邮箱已注册" : "此手机号已注册");
|
||||
}
|
||||
if (contactType == 0) {
|
||||
if (!supportsEmailLogin) {
|
||||
recordLogService.saveLogs(username, startTime, "邮箱登录不支持", "邮箱登录未开启", null, "失败");
|
||||
throw new ServiceException("邮箱登录未开启");
|
||||
}
|
||||
emailService.sendSimpleEmail(username);
|
||||
} else {
|
||||
if (!supportsPhoneLogin) {
|
||||
recordLogService.saveLogs(username, startTime, "手机登录不支持", "手机登录未开启", null, "失败");
|
||||
throw new ServiceException("手机登录未开启");
|
||||
}
|
||||
passwordService.createPhoneCaptcha(username);
|
||||
}
|
||||
recordLogService.saveLogs(username, startTime, contactType == 0 ? "获取邮箱验证码" : "获取手机验证码",
|
||||
contactType == 0 ? "邮箱注册" : "手机号注册", null, "成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理登录操作
|
||||
*
|
||||
* @param username 用户名或手机号
|
||||
* @param startTime 操作开始时间
|
||||
* @param contactType 联系方式类型(0:邮箱,1:手机号,2:无效)
|
||||
* @param userExists 用户是否存在
|
||||
*/
|
||||
private void handleLogin(String username, long startTime, int contactType, boolean userExists) {
|
||||
if (!userExists) {
|
||||
recordLogService.saveLogs(username, startTime, "登录用户不存在", "手机号未注册", null, "失败");
|
||||
throw new ServiceException("登录用户不存在");
|
||||
}
|
||||
if (contactType == 0) {
|
||||
if (!supportsEmailLogin) {
|
||||
recordLogService.saveLogs(username, startTime, "邮箱登录不支持", "邮箱登录未开启", null, "失败");
|
||||
throw new ServiceException("邮箱登录未开启");
|
||||
}
|
||||
emailService.sendSimpleEmail(username);
|
||||
} else {
|
||||
if (!supportsPhoneLogin) {
|
||||
recordLogService.saveLogs(username, startTime, "手机登录不支持", "手机登录未开启", null, "失败");
|
||||
throw new ServiceException("手机登录未开启");
|
||||
}
|
||||
passwordService.createPhoneCaptcha(username);
|
||||
}
|
||||
recordLogService.saveLogs(username, startTime, "获取验证码", "用户存在", null, "成功");
|
||||
return R.ok(strategyFactory.sendVerificationCode(username));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -182,9 +96,7 @@ public class SysLoginService {
|
|||
sysUser.setStatus("1");
|
||||
sysUser.setApprovalStatus("0");
|
||||
//有要求另加
|
||||
|
||||
sysUser.setPassword(SecurityUtils.encryptPassword(registerBody.getPassword()));
|
||||
|
||||
if (getContactType(registerBody.getMobile()) == 1) {
|
||||
sysUser.setPhonenumber(registerBody.getMobile());
|
||||
} else {
|
||||
|
|
@ -214,7 +126,6 @@ public class SysLoginService {
|
|||
public static int getContactType(String contactInfo) {
|
||||
String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
|
||||
String phoneRegex = "^1[3-9]\\d{9}$";
|
||||
|
||||
if (contactInfo.matches(emailRegex)) {
|
||||
return 0;
|
||||
} else if (contactInfo.matches(phoneRegex)) {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public class SysPasswordService {
|
|||
}
|
||||
String code = VerificationCodeUtils.generateVerificationCode(VerificationCodeUtils.CodeType.NUMERIC);
|
||||
String str = "您的验证码为" + code + ",尊敬的客户,以上验证码3分钟有效,微服务平台提醒您:转发可能导致账号被盗,请勿将验证码泄露于他人";
|
||||
String verifyKey = CacheConstants.CAPTCHA_PHONE_CODE_KEY + phone;
|
||||
String verifyKey = CacheConstants.VERIFICATION_CODE + phone;
|
||||
String s = SmsUtils.smsToken(phone, str, "");
|
||||
if (StringUtils.isNotEmpty(s)) {
|
||||
if (s.contains("ok")) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.bonus.auth.service;
|
||||
|
||||
public interface VerificationCodeStrategy {
|
||||
/**
|
||||
* @param contactInfo 可以是邮箱地址或手机号码
|
||||
*/
|
||||
String sendVerificationCode(String contactInfo);
|
||||
}
|
||||
|
|
@ -33,6 +33,10 @@
|
|||
<groupId>com.bonus</groupId>
|
||||
<artifactId>bonus-common-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.bonus.common.security.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "verification-code")
|
||||
@Data
|
||||
public class VerificationCodeConfig {
|
||||
/**
|
||||
* 主题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 过期时长
|
||||
*/
|
||||
private Long time;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String content;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.bonus.common.security.service;
|
||||
|
||||
import com.bonus.common.core.constant.CacheConstants;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.utils.VerificationCodeUtils;
|
||||
import com.bonus.common.redis.service.RedisService;
|
||||
import com.bonus.common.security.config.VerificationCodeConfig;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.bonus.common.core.utils.VerificationCodeUtils.CodeType.NUMERIC;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
@Service
|
||||
public class EmailService {
|
||||
@Resource
|
||||
private VerificationCodeConfig verificationCodeConfig;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
@Resource
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
/**
|
||||
* 发送简单邮件
|
||||
*
|
||||
* @param to 接收者邮箱地址
|
||||
*/
|
||||
public String sendSimpleEmail(String to) {
|
||||
String code = VerificationCodeUtils.generateVerificationCode(NUMERIC);
|
||||
String str = verificationCodeConfig.getContent().replace("<code>", code);
|
||||
str = str.replace("<time>", verificationCodeConfig.getTime().toString());
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
// 发件人邮箱地址
|
||||
message.setFrom("2642480752@qq.com");
|
||||
// 收件人邮箱地址
|
||||
message.setTo(to);
|
||||
// 邮件主题
|
||||
message.setSubject(verificationCodeConfig.getTitle());
|
||||
// 邮件内容
|
||||
message.setText(str);
|
||||
// 发送邮件
|
||||
mailSender.send(message);
|
||||
String uuid = StringUtils.randomUUID();
|
||||
String verifyKey = CacheConstants.VERIFICATION_CODE + uuid;
|
||||
redisService.setCacheObject(verifyKey, code, verificationCodeConfig.getTime(), TimeUnit.MINUTES);
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.bonus.common.security.service;
|
||||
|
||||
import com.bonus.common.core.constant.CacheConstants;
|
||||
import com.bonus.common.core.exception.CaptchaException;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.utils.VerificationCodeUtils;
|
||||
import com.bonus.common.core.utils.sms.SmsUtils;
|
||||
import com.bonus.common.redis.service.RedisService;
|
||||
import com.bonus.common.security.config.VerificationCodeConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.bonus.common.core.utils.VerificationCodeUtils.CodeType.NUMERIC;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
@Component
|
||||
public class SmsService {
|
||||
@Resource
|
||||
private VerificationCodeConfig verificationCodeConfig;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 生成手机验证码
|
||||
*
|
||||
* @return AjaxResult
|
||||
* @throws CaptchaException 自定义captcha 异常
|
||||
*/
|
||||
public String sendSimplePhone(String to) {
|
||||
if (StringUtils.isEmpty(to)) {
|
||||
throw new CaptchaException("手机号不能为空");
|
||||
}
|
||||
String code = VerificationCodeUtils.generateVerificationCode(NUMERIC);
|
||||
String str = verificationCodeConfig.getContent().replace("<code>", code);
|
||||
str = str.replace("<time>", verificationCodeConfig.getTime().toString());
|
||||
String s = SmsUtils.smsToken(to, str, "");
|
||||
if (StringUtils.isNotEmpty(s)) {
|
||||
if (s.contains("ok")) {
|
||||
String uuid = StringUtils.randomUUID();
|
||||
String verifyKey = CacheConstants.VERIFICATION_CODE + uuid;
|
||||
redisService.setCacheObject(verifyKey, code, verificationCodeConfig.getTime(), TimeUnit.MINUTES);
|
||||
return uuid;
|
||||
} else {
|
||||
throw new CaptchaException("获取短信失败");
|
||||
}
|
||||
} else {
|
||||
throw new CaptchaException("获取短信失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,5 @@
|
|||
package com.bonus.common.security.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.exception.CaptchaException;
|
||||
import com.bonus.common.core.utils.VerificationCodeUtils;
|
||||
import com.bonus.common.core.utils.sms.SmsUtils;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.bonus.common.core.constant.CacheConstants;
|
||||
import com.bonus.common.core.constant.SecurityConstants;
|
||||
import com.bonus.common.core.utils.JwtUtils;
|
||||
|
|
@ -26,6 +10,16 @@ import com.bonus.common.core.utils.uuid.IdUtils;
|
|||
import com.bonus.common.redis.service.RedisService;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
import com.bonus.system.api.model.LoginUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* token验证处理
|
||||
|
|
@ -34,6 +28,9 @@ import com.bonus.system.api.model.LoginUser;
|
|||
*/
|
||||
@Component
|
||||
public class TokenService {
|
||||
@Value("${tokenTime}")
|
||||
private Long tokenTime;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
|
||||
|
||||
@Autowired
|
||||
|
|
@ -48,6 +45,7 @@ public class TokenService {
|
|||
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
|
||||
|
||||
private final static String LOGIN_USER_KEY = CacheConstants.LOGIN_USER_KEY;
|
||||
|
||||
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
|
||||
|
||||
/**
|
||||
|
|
@ -74,7 +72,7 @@ public class TokenService {
|
|||
rspMap.put("access_token", accessToken);
|
||||
rspMap.put("expires_in", EXPIRETIME);
|
||||
//对token进行存储
|
||||
redisService.setCacheObject(LOGIN_USER_KEY + userId, token, 120L, TimeUnit.MINUTES);
|
||||
redisService.setCacheObject(LOGIN_USER_KEY + userId, token, tokenTime, TimeUnit.MINUTES);
|
||||
return rspMap;
|
||||
}
|
||||
|
||||
|
|
@ -176,10 +174,10 @@ public class TokenService {
|
|||
*/
|
||||
public void refreshToken(LoginUser loginUser) {
|
||||
loginUser.setLoginTime(System.currentTimeMillis());
|
||||
loginUser.setExpireTime(loginUser.getLoginTime() + EXPIRETIME * MILLIS_MINUTE);
|
||||
loginUser.setExpireTime(loginUser.getLoginTime() + tokenTime * MILLIS_MINUTE);
|
||||
// 根据uuid将loginUser缓存
|
||||
String userKey = getTokenKey(loginUser.getToken());
|
||||
redisService.setCacheObject(userKey, loginUser, EXPIRETIME, TimeUnit.MINUTES);
|
||||
redisService.setCacheObject(userKey, loginUser, tokenTime, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
private String getTokenKey(String token) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
com.bonus.common.security.config.WebMvcConfig
|
||||
com.bonus.common.security.config.VerificationCodeConfig
|
||||
com.bonus.common.security.service.TokenService
|
||||
com.bonus.common.security.service.SmsService
|
||||
com.bonus.common.security.service.EmailService
|
||||
com.bonus.common.security.aspect.PreAuthorizeAspect
|
||||
com.bonus.common.security.aspect.InnerAuthAspect
|
||||
com.bonus.common.security.handler.GlobalExceptionHandler
|
||||
|
|
|
|||
Loading…
Reference in New Issue