手机号认证
This commit is contained in:
parent
62c9824426
commit
4c085cff34
@ -0,0 +1,37 @@
|
||||
package com.ruoyi.oauth.common.enums;
|
||||
|
||||
public enum OauthVerificationUse {
|
||||
|
||||
LOGIN("登录", "login"),
|
||||
REGISTER("注册", "register"),
|
||||
DISABLE("禁用", "disable"),
|
||||
RESET_PASSWORD("重置密码", "reset_password"),
|
||||
RESET_PHONE("重置手机号", "reset_phone"),
|
||||
Other("其他","other");
|
||||
|
||||
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private OauthVerificationUse(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ruoyi.oauth.common.service;
|
||||
|
||||
import com.ruoyi.oauth.common.enums.OauthVerificationUse;
|
||||
|
||||
/**
|
||||
* code认证方式接口
|
||||
*
|
||||
* @author zlh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public interface OauthVerificationCodeService {
|
||||
public boolean sendCode(String o, String code,OauthVerificationUse use) throws Exception;
|
||||
public String checkCode(String o, String code,OauthVerificationUse use) throws Exception;
|
||||
|
||||
}
|
@ -3,6 +3,12 @@ package com.ruoyi.oauth.phone.constant;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 手机号认证数据
|
||||
*
|
||||
* @author Dftre
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
@Component
|
||||
public class DySmsConstant {
|
||||
@Value("${oauth.phone.dysms.appId}")
|
||||
|
@ -1,24 +1,153 @@
|
||||
package com.ruoyi.oauth.phone.controller;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginBody;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.oauth.common.enums.OauthVerificationUse;
|
||||
import com.ruoyi.oauth.phone.service.DySmsService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
|
||||
|
||||
/**
|
||||
* 手机号认证Controller
|
||||
*
|
||||
* @author zlh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
@RestController
|
||||
@Anonymous
|
||||
@RequestMapping("/oauth/phone")
|
||||
public class DySmsController {
|
||||
public class DySmsController extends BaseController {
|
||||
@Autowired
|
||||
public DySmsService dySmsService;
|
||||
@PostMapping("/login")
|
||||
public String postMethodName() {
|
||||
dySmsService.doLogin("17854126030");
|
||||
return null;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Anonymous
|
||||
@PostMapping("/sendcode/{mode}") // 发送验证码
|
||||
public AjaxResult sendcode(@RequestBody LoginBody loginBody, @PathVariable(value = "mode") String mode)
|
||||
throws Exception {
|
||||
try {
|
||||
OauthVerificationUse oauthVerificationUse = null;
|
||||
switch (mode) {
|
||||
case "login":
|
||||
oauthVerificationUse = OauthVerificationUse.LOGIN;
|
||||
break;
|
||||
case "register":
|
||||
oauthVerificationUse = OauthVerificationUse.REGISTER;
|
||||
break;
|
||||
case "disable":
|
||||
oauthVerificationUse = OauthVerificationUse.DISABLE;
|
||||
break;
|
||||
case "resetpassword":
|
||||
oauthVerificationUse = OauthVerificationUse.RESET_PASSWORD;
|
||||
break;
|
||||
case "resetphone":
|
||||
oauthVerificationUse = OauthVerificationUse.RESET_PHONE;
|
||||
break;
|
||||
default:
|
||||
oauthVerificationUse = OauthVerificationUse.Other;
|
||||
}
|
||||
String code = generateRandomString(6);
|
||||
dySmsService.sendCode(loginBody.getUsername(), code, oauthVerificationUse);
|
||||
return AjaxResult.success("发送验证码成功");
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("发送验证码失败,原因: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static String generateRandomString(int n) {
|
||||
String characters = "0123456789"; // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
StringBuilder result = new StringBuilder();
|
||||
Random random = new Random();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int index = random.nextInt(characters.length());
|
||||
result.append(characters.charAt(index));
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Anonymous
|
||||
@PostMapping("/login") // 登录
|
||||
public AjaxResult postMethodName(@RequestBody LoginBody loginBody) throws Exception {
|
||||
if (dySmsService.checkCode(loginBody.getUsername(), loginBody.getCode(),
|
||||
OauthVerificationUse.LOGIN) == "false") {
|
||||
return AjaxResult.error("登录失败");
|
||||
} else {
|
||||
return AjaxResult.success("登录成功");
|
||||
}
|
||||
}
|
||||
|
||||
@Anonymous
|
||||
@PostMapping("/register") // 注册
|
||||
public AjaxResult postenroll(@RequestBody LoginBody loginBody) throws Exception {
|
||||
try {
|
||||
dySmsService.checkCode(loginBody.getUsername(), loginBody.getCode(), OauthVerificationUse.REGISTER);
|
||||
// 验证通过,执行注册逻辑
|
||||
SysUser user = new SysUser();
|
||||
user.setUserName(loginBody.getUsername());
|
||||
user.setNickName(loginBody.getUsername());
|
||||
user.setPassword(SecurityUtils.encryptPassword(loginBody.getPassword()));
|
||||
user.setPhonenumber(loginBody.getUsername());
|
||||
userService.insertUser(user);
|
||||
return AjaxResult.success("注册成功");
|
||||
} catch (Exception e) {
|
||||
// return "注册失败,原因: " + e.getMessage();
|
||||
return AjaxResult.error("注册失败");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/disable") // 注销
|
||||
public AjaxResult postlogout(@RequestBody LoginBody loginBody) throws Exception {
|
||||
try {
|
||||
dySmsService.checkCode(getUsername(), loginBody.getCode(), OauthVerificationUse.DISABLE);
|
||||
// 验证通过,执行注销逻辑
|
||||
SysUser sysUser = userService.selectUserByPhone(loginBody.getUsername());
|
||||
userService.deleteUserById(sysUser.getUserId());
|
||||
return AjaxResult.success("注销成功");
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("注销失败,原因: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@Anonymous
|
||||
@PostMapping("/resetpassword") // 重置密码
|
||||
public AjaxResult postpassword(@RequestBody LoginBody loginBody) throws Exception {
|
||||
try {
|
||||
dySmsService.checkCode(loginBody.getUsername(), loginBody.getCode(), OauthVerificationUse.RESET_PASSWORD);
|
||||
// 验证通过,执行重置密码逻辑
|
||||
SysUser sysUser = userService.selectUserByPhone(loginBody.getUsername());
|
||||
sysUser.setPassword(SecurityUtils.encryptPassword(loginBody.getPassword()));
|
||||
userService.updateUser(sysUser);
|
||||
return AjaxResult.success("重置密码成功");
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("重置密码失败,原因: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/resetphone") // 重置手机号
|
||||
public AjaxResult postphone(@RequestBody LoginBody loginBody) throws Exception {
|
||||
try {
|
||||
dySmsService.checkCode(loginBody.getUsername(), loginBody.getCode(), OauthVerificationUse.RESET_PHONE);
|
||||
// 验证通过,执行重置密码逻辑
|
||||
SysUser sysUser = userService.selectUserByUserName(getUsername());
|
||||
sysUser.setPhonenumber(loginBody.getUsername());
|
||||
userService.updateUser(sysUser);
|
||||
return AjaxResult.success("重置手机号成功");
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("重置手机号失败,原因: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,12 @@ package com.ruoyi.oauth.phone.enums;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 手机号认证短信模板
|
||||
*
|
||||
* @author Dftre
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public enum DySmsTemplate {
|
||||
/** 登录短信模板编码 */
|
||||
LOGIN_TEMPLATE_CODE("SMS_175435174", "Ruoyi", "code"),
|
||||
|
@ -1,5 +1,21 @@
|
||||
package com.ruoyi.oauth.phone.service;
|
||||
|
||||
import com.ruoyi.oauth.common.enums.OauthVerificationUse;
|
||||
|
||||
/**
|
||||
* 手机号认证Servcie
|
||||
*
|
||||
* @author zlh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public interface DySmsService {
|
||||
public String doLogin(String phone);
|
||||
|
||||
public boolean sendCode(String phone, String code, OauthVerificationUse use) throws Exception;
|
||||
|
||||
public String checkCode(String phone, String code, OauthVerificationUse use) throws Exception;
|
||||
|
||||
// public String doenroll(String phone,String username, String password);
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package com.ruoyi.oauth.phone.service.Impl;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -13,13 +15,21 @@ import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.framework.web.service.TokenService;
|
||||
import com.ruoyi.framework.web.service.UserDetailsServiceImpl;
|
||||
import com.ruoyi.oauth.common.enums.OauthVerificationUse;
|
||||
import com.ruoyi.oauth.common.service.OauthVerificationCodeService;
|
||||
import com.ruoyi.oauth.phone.enums.DySmsTemplate;
|
||||
import com.ruoyi.oauth.phone.service.DySmsService;
|
||||
import com.ruoyi.oauth.phone.utils.DySmsUtil;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
|
||||
/**
|
||||
* 手机号认证Servcie
|
||||
*
|
||||
* @author zlh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
@Service
|
||||
public class DySmsServiceImpl implements DySmsService {
|
||||
public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeService {
|
||||
|
||||
@Autowired
|
||||
private DySmsUtil dySmsUtil;
|
||||
@ -32,6 +42,83 @@ public class DySmsServiceImpl implements DySmsService {
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DySmsServiceImpl.class);
|
||||
|
||||
|
||||
public boolean beforeSendCode(String phone, OauthVerificationUse use) throws Exception {//1.查验手机号是否存在,分辨登录和删除用户以及注册用户
|
||||
boolean havePhoneFlag= userService.selectUserByPhone(phone) != null;
|
||||
if((use.equals(OauthVerificationUse.LOGIN ) || use.equals(OauthVerificationUse.DISABLE )||use.equals(OauthVerificationUse.RESET_PASSWORD) )&& !havePhoneFlag){
|
||||
throw new ServiceException("该手机号未绑定用户");
|
||||
}else if((use.equals(OauthVerificationUse.REGISTER ) ||use.equals(OauthVerificationUse.RESET_PHONE))&& havePhoneFlag){
|
||||
throw new ServiceException("该手机号已绑定用户");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendCode(String phone, String code, OauthVerificationUse use) throws Exception {//1.查验手机号是否存在,分辨登录和删除用户以及注册用户
|
||||
//限制短信一分钟只能发送一次短信
|
||||
String cacheKey = "phone_codes_" + use.getValue() + "_" + phone;
|
||||
if(redisCache.hasKey(cacheKey)){
|
||||
throw new ServiceException("请在1分钟后再发送短信");
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject templateParams = new JSONObject();
|
||||
templateParams.put("code", code);
|
||||
dySmsUtil.sendSms(DySmsTemplate.Test_TEMPLATE_CODE, templateParams, phone);
|
||||
redisCache.setCacheObject("phone_codes_" + use.getValue() + "_" + phone, code, 1, TimeUnit.MINUTES);
|
||||
log.info("发送手机验证码成功:{ phone: " + phone + " code:" + code + "}");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("发送手机验证码异常:" + phone);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String checkCode(String phone, String code, OauthVerificationUse use) throws Exception{
|
||||
String cacheKey = "phone_codes_" + use.getValue() + "_" + phone;
|
||||
String cachedCode = redisCache.getCacheObject(cacheKey); // 从缓存中获取验证码
|
||||
boolean havePhoneFlag= userService.selectUserByPhone(phone) != null;
|
||||
if(use.equals(OauthVerificationUse.LOGIN ) && havePhoneFlag){//登录校验
|
||||
if (code.equals(cachedCode)) {
|
||||
SysUser sysUser = userService.selectUserByPhone(phone);
|
||||
LoginUser loginUser = (LoginUser) userDetailsServiceImpl.createLoginUser(sysUser);
|
||||
return tokenService.createToken(loginUser);
|
||||
// return true;
|
||||
} else {
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
}else if(use.equals(OauthVerificationUse.REGISTER )&& !havePhoneFlag){//注册校验
|
||||
if (code.equals(cachedCode)) {
|
||||
return Boolean.toString(true);
|
||||
} else {
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
}else if(use.equals(OauthVerificationUse.DISABLE )&& havePhoneFlag){//注销校验
|
||||
if (code.equals(cachedCode)) {
|
||||
return Boolean.toString(true);
|
||||
} else {
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
}else if(use.equals(OauthVerificationUse.RESET_PASSWORD )&& havePhoneFlag){//重置密码校验
|
||||
if (code.equals(cachedCode)) {
|
||||
return Boolean.toString(true);
|
||||
} else {
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
}else if(use.equals(OauthVerificationUse.RESET_PHONE )&& !havePhoneFlag){//重置账号校验
|
||||
if (code.equals(cachedCode)) {
|
||||
return Boolean.toString(true);
|
||||
} else {
|
||||
throw new ServiceException("验证码错误");
|
||||
}
|
||||
}
|
||||
return Boolean.toString(false);
|
||||
}
|
||||
|
||||
public static String generateRandomString(int n) {
|
||||
String characters = "0123456789"; // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
Loading…
Reference in New Issue
Block a user