新增短信登录功能
This commit is contained in:
parent
b5010197d3
commit
0f09fce119
|
|
@ -0,0 +1,39 @@
|
||||||
|
package net.maku.api.module.message;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信服务API
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
public interface SmsApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
* @param params 参数
|
||||||
|
* @return 是否发送成功
|
||||||
|
*/
|
||||||
|
boolean send(String mobile, Map<String, String> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
* @param key 参数KEY
|
||||||
|
* @param value 参数Value
|
||||||
|
* @return 是否发送成功
|
||||||
|
*/
|
||||||
|
boolean sendCode(String mobile, String key, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 效验短信验证码
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
* @param code 验证码
|
||||||
|
* @return 是否效验成功
|
||||||
|
*/
|
||||||
|
boolean verifyCode(String mobile, String code);
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,11 @@
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
<groupId>net.maku</groupId>
|
||||||
|
<artifactId>fast-boot-api</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
<groupId>com.aliyun</groupId>
|
<groupId>com.aliyun</groupId>
|
||||||
<artifactId>dysmsapi20170525</artifactId>
|
<artifactId>dysmsapi20170525</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
@ -31,6 +36,7 @@
|
||||||
<groupId>com.qiniu</groupId>
|
<groupId>com.qiniu</groupId>
|
||||||
<artifactId>qiniu-java-sdk</artifactId>
|
<artifactId>qiniu-java-sdk</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package net.maku.message.api;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.maku.api.module.message.SmsApi;
|
||||||
|
import net.maku.message.cache.SmsSendCache;
|
||||||
|
import net.maku.message.sms.service.SmsService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信服务Api
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SmsApiImpl implements SmsApi {
|
||||||
|
private final SmsService smsService;
|
||||||
|
private final SmsSendCache smsSendCache;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean send(String mobile, Map<String, String> params) {
|
||||||
|
return smsService.send(mobile, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendCode(String mobile, String key, String value) {
|
||||||
|
// 短信参数
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put(key, value);
|
||||||
|
|
||||||
|
// 发送短信
|
||||||
|
boolean flag = smsService.send(mobile, params);
|
||||||
|
if (flag) {
|
||||||
|
smsSendCache.saveCode(mobile, value);
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verifyCode(String mobile, String code) {
|
||||||
|
String value = smsSendCache.getCode(mobile);
|
||||||
|
if (value != null) {
|
||||||
|
// 删除短信验证码
|
||||||
|
smsSendCache.deleteCode(mobile);
|
||||||
|
|
||||||
|
// 效验
|
||||||
|
return value.equalsIgnoreCase(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
fast-boot-module/fast-boot-message/src/main/java/net/maku/message/cache/SmsSendCache.java
vendored
Normal file
43
fast-boot-module/fast-boot-message/src/main/java/net/maku/message/cache/SmsSendCache.java
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
package net.maku.message.cache;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.maku.framework.common.cache.RedisCache;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送 Cache
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SmsSendCache {
|
||||||
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取发送手机短信验证码KEY
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
* @return KEY
|
||||||
|
*/
|
||||||
|
private String getCodeKey(String mobile) {
|
||||||
|
return "message:sms:code" + mobile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveCode(String mobile, String code) {
|
||||||
|
String key = getCodeKey(mobile);
|
||||||
|
|
||||||
|
// 保存到Redis,有效期10分钟
|
||||||
|
redisCache.set(key, code, 10 * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode(String mobile) {
|
||||||
|
String key = getCodeKey(mobile);
|
||||||
|
return (String) redisCache.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteCode(String mobile) {
|
||||||
|
String key = getCodeKey(mobile);
|
||||||
|
redisCache.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.maku.security.service;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.maku.framework.security.mobile.MobileUserDetailsService;
|
||||||
|
import net.maku.system.dao.SysUserDao;
|
||||||
|
import net.maku.system.entity.SysUserEntity;
|
||||||
|
import net.maku.system.service.SysUserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机验证码登录 MobileUserDetailsService
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MobileUserDetailsServiceImpl implements MobileUserDetailsService {
|
||||||
|
private final SysUserDetailsService sysUserDetailsService;
|
||||||
|
private final SysUserDao sysUserDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByMobile(String mobile) throws UsernameNotFoundException {
|
||||||
|
SysUserEntity userEntity = sysUserDao.getByMobile(mobile);
|
||||||
|
if (userEntity == null) {
|
||||||
|
throw new UsernameNotFoundException("手机号或验证码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sysUserDetailsService.getUserDetails(userEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package net.maku.security.service;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.maku.api.module.message.SmsApi;
|
||||||
|
import net.maku.framework.security.mobile.MobileVerifyCodeService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信验证码效验
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MobileVerifyCodeServiceImpl implements MobileVerifyCodeService {
|
||||||
|
private final SmsApi smsApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verifyCode(String mobile, String code) {
|
||||||
|
return smsApi.verifyCode(mobile, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.maku.security.service;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.maku.system.dao.SysUserDao;
|
||||||
|
import net.maku.system.entity.SysUserEntity;
|
||||||
|
import net.maku.system.service.SysUserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号登录 UserDetailsService
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
|
private final SysUserDetailsService sysUserDetailsService;
|
||||||
|
private final SysUserDao sysUserDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
SysUserEntity userEntity = sysUserDao.getByUsername(username);
|
||||||
|
if (userEntity == null) {
|
||||||
|
throw new UsernameNotFoundException("用户名或密码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sysUserDetailsService.getUserDetails(userEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,28 +1,19 @@
|
||||||
package net.maku.system.controller;
|
package net.maku.system.controller;
|
||||||
|
|
||||||
import cn.hutool.core.lang.UUID;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import net.maku.framework.common.constant.Constant;
|
|
||||||
import net.maku.framework.common.utils.Result;
|
import net.maku.framework.common.utils.Result;
|
||||||
import net.maku.framework.security.cache.TokenStoreCache;
|
|
||||||
import net.maku.framework.security.user.UserDetail;
|
|
||||||
import net.maku.framework.security.utils.TokenUtils;
|
import net.maku.framework.security.utils.TokenUtils;
|
||||||
import net.maku.system.enums.LoginOperationEnum;
|
import net.maku.system.service.SysAuthService;
|
||||||
import net.maku.system.service.SysCaptchaService;
|
import net.maku.system.service.SysCaptchaService;
|
||||||
import net.maku.system.service.SysLogLoginService;
|
import net.maku.system.vo.SysAccountLoginVO;
|
||||||
import net.maku.system.vo.SysLoginVO;
|
import net.maku.system.vo.SysCaptchaVO;
|
||||||
|
import net.maku.system.vo.SysMobileLoginVO;
|
||||||
import net.maku.system.vo.SysTokenVO;
|
import net.maku.system.vo.SysTokenVO;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证管理
|
* 认证管理
|
||||||
|
|
@ -35,72 +26,44 @@ import java.util.Map;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class SysAuthController {
|
public class SysAuthController {
|
||||||
private final SysCaptchaService sysCaptchaService;
|
private final SysCaptchaService sysCaptchaService;
|
||||||
private final TokenStoreCache tokenStoreCache;
|
private final SysAuthService sysAuthService;
|
||||||
private final AuthenticationManager authenticationManager;
|
|
||||||
private final SysLogLoginService sysLogLoginService;
|
|
||||||
|
|
||||||
@GetMapping("captcha")
|
@GetMapping("captcha")
|
||||||
@Operation(summary = "验证码")
|
@Operation(summary = "验证码")
|
||||||
public Result<Map<String, Object>> captcha() {
|
public Result<SysCaptchaVO> captcha() {
|
||||||
// 生成key
|
SysCaptchaVO captchaVO = sysCaptchaService.generate();
|
||||||
String key = UUID.randomUUID().toString();
|
|
||||||
// 生成base64验证码
|
|
||||||
String image = sysCaptchaService.generate(key);
|
|
||||||
|
|
||||||
// 封装返回数据
|
return Result.ok(captchaVO);
|
||||||
Map<String, Object> data = new HashMap<>();
|
|
||||||
data.put("key", key);
|
|
||||||
data.put("image", image);
|
|
||||||
|
|
||||||
return Result.ok(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("login")
|
@PostMapping("login")
|
||||||
@Operation(summary = "登录")
|
@Operation(summary = "账号密码登录")
|
||||||
public Result<SysTokenVO> login(@RequestBody SysLoginVO login) {
|
public Result<SysTokenVO> login(@RequestBody SysAccountLoginVO login) {
|
||||||
// 验证码效验
|
SysTokenVO token = sysAuthService.loginByAccount(login);
|
||||||
boolean flag = sysCaptchaService.validate(login.getKey(), login.getCaptcha());
|
|
||||||
if (!flag) {
|
|
||||||
// 保存登录日志
|
|
||||||
sysLogLoginService.save(login.getUsername(), Constant.FAIL, LoginOperationEnum.CAPTCHA_FAIL.getValue());
|
|
||||||
|
|
||||||
return Result.error("验证码错误");
|
return Result.ok(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
Authentication authentication;
|
@PostMapping("send/code")
|
||||||
try {
|
@Operation(summary = "发送短信验证码")
|
||||||
// 用户认证
|
public Result<String> sendCode(String mobile) {
|
||||||
authentication = authenticationManager.authenticate(
|
sysAuthService.sendCode(mobile);
|
||||||
new UsernamePasswordAuthenticationToken(login.getUsername(), login.getPassword()));
|
|
||||||
} catch (BadCredentialsException e) {
|
return Result.ok();
|
||||||
return Result.error("用户名密码错误");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户信息
|
@PostMapping("mobile")
|
||||||
UserDetail user = (UserDetail) authentication.getPrincipal();
|
@Operation(summary = "手机号登录")
|
||||||
|
public Result<SysTokenVO> mobile(@RequestBody SysMobileLoginVO login) {
|
||||||
|
SysTokenVO token = sysAuthService.loginByMobile(login);
|
||||||
|
|
||||||
// 生成 accessToken
|
return Result.ok(token);
|
||||||
String accessToken = TokenUtils.generator();
|
|
||||||
|
|
||||||
// 保存用户信息到缓存
|
|
||||||
tokenStoreCache.saveUser(accessToken, user);
|
|
||||||
|
|
||||||
return Result.ok(new SysTokenVO(accessToken));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("logout")
|
@PostMapping("logout")
|
||||||
@Operation(summary = "退出")
|
@Operation(summary = "退出")
|
||||||
public Result<String> logout(HttpServletRequest request) {
|
public Result<String> logout(HttpServletRequest request) {
|
||||||
String accessToken = TokenUtils.getAccessToken(request);
|
sysAuthService.logout(TokenUtils.getAccessToken(request));
|
||||||
|
|
||||||
// 用户信息
|
|
||||||
UserDetail user = tokenStoreCache.getUser(accessToken);
|
|
||||||
|
|
||||||
// 删除用户信息
|
|
||||||
tokenStoreCache.deleteUser(accessToken);
|
|
||||||
|
|
||||||
// 保存登录日志
|
|
||||||
sysLogLoginService.save(user.getUsername(), Constant.SUCCESS, LoginOperationEnum.LOGOUT_SUCCESS.getValue());
|
|
||||||
|
|
||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package net.maku.system.service;
|
||||||
|
|
||||||
|
import net.maku.system.vo.SysAccountLoginVO;
|
||||||
|
import net.maku.system.vo.SysMobileLoginVO;
|
||||||
|
import net.maku.system.vo.SysTokenVO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限认证服务
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
public interface SysAuthService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号密码登录
|
||||||
|
*
|
||||||
|
* @param login 登录信息
|
||||||
|
*/
|
||||||
|
SysTokenVO loginByAccount(SysAccountLoginVO login);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机短信登录
|
||||||
|
*
|
||||||
|
* @param login 登录信息
|
||||||
|
*/
|
||||||
|
SysTokenVO loginByMobile(SysMobileLoginVO login);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送手机验证码
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
*/
|
||||||
|
void sendCode(String mobile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出登录
|
||||||
|
*
|
||||||
|
* @param accessToken accessToken
|
||||||
|
*/
|
||||||
|
void logout(String accessToken);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package net.maku.system.service;
|
package net.maku.system.service;
|
||||||
|
|
||||||
|
import net.maku.system.vo.SysCaptchaVO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码
|
* 验证码
|
||||||
*
|
*
|
||||||
|
|
@ -8,11 +10,8 @@ package net.maku.system.service;
|
||||||
public interface SysCaptchaService {
|
public interface SysCaptchaService {
|
||||||
/**
|
/**
|
||||||
* 生成验证码
|
* 生成验证码
|
||||||
*
|
|
||||||
* @param key key
|
|
||||||
* @return 返回base64图片验证码
|
|
||||||
*/
|
*/
|
||||||
String generate(String key);
|
SysCaptchaVO generate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码效验
|
* 验证码效验
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.maku.system.service;
|
||||||
|
|
||||||
|
import net.maku.system.entity.SysUserEntity;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
public interface SysUserDetailsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 UserDetails 对象
|
||||||
|
*/
|
||||||
|
UserDetails getUserDetails(SysUserEntity userEntity);
|
||||||
|
}
|
||||||
|
|
@ -24,8 +24,11 @@ public interface SysUserService extends BaseService<SysUserEntity> {
|
||||||
|
|
||||||
void delete(List<Long> idList);
|
void delete(List<Long> idList);
|
||||||
|
|
||||||
|
SysUserVO getByMobile(String mobile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改密码
|
* 修改密码
|
||||||
|
*
|
||||||
* @param id 用户ID
|
* @param id 用户ID
|
||||||
* @param newPassword 新密码
|
* @param newPassword 新密码
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
package net.maku.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.maku.api.module.message.SmsApi;
|
||||||
|
import net.maku.framework.common.constant.Constant;
|
||||||
|
import net.maku.framework.common.exception.FastException;
|
||||||
|
import net.maku.framework.security.cache.TokenStoreCache;
|
||||||
|
import net.maku.framework.security.mobile.MobileAuthenticationToken;
|
||||||
|
import net.maku.framework.security.user.UserDetail;
|
||||||
|
import net.maku.framework.security.utils.TokenUtils;
|
||||||
|
import net.maku.system.enums.LoginOperationEnum;
|
||||||
|
import net.maku.system.service.SysAuthService;
|
||||||
|
import net.maku.system.service.SysCaptchaService;
|
||||||
|
import net.maku.system.service.SysLogLoginService;
|
||||||
|
import net.maku.system.service.SysUserService;
|
||||||
|
import net.maku.system.vo.SysAccountLoginVO;
|
||||||
|
import net.maku.system.vo.SysMobileLoginVO;
|
||||||
|
import net.maku.system.vo.SysTokenVO;
|
||||||
|
import net.maku.system.vo.SysUserVO;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限认证服务
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SysAuthServiceImpl implements SysAuthService {
|
||||||
|
private final SysCaptchaService sysCaptchaService;
|
||||||
|
private final TokenStoreCache tokenStoreCache;
|
||||||
|
private final AuthenticationManager authenticationManager;
|
||||||
|
private final SysLogLoginService sysLogLoginService;
|
||||||
|
private final SysUserService sysUserService;
|
||||||
|
private final SmsApi smsApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysTokenVO loginByAccount(SysAccountLoginVO login) {
|
||||||
|
// 验证码效验
|
||||||
|
boolean flag = sysCaptchaService.validate(login.getKey(), login.getCaptcha());
|
||||||
|
if (!flag) {
|
||||||
|
// 保存登录日志
|
||||||
|
sysLogLoginService.save(login.getUsername(), Constant.FAIL, LoginOperationEnum.CAPTCHA_FAIL.getValue());
|
||||||
|
|
||||||
|
throw new FastException("验证码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
Authentication authentication;
|
||||||
|
try {
|
||||||
|
// 用户认证
|
||||||
|
authentication = authenticationManager.authenticate(
|
||||||
|
new UsernamePasswordAuthenticationToken(login.getUsername(), login.getPassword()));
|
||||||
|
} catch (BadCredentialsException e) {
|
||||||
|
throw new FastException("用户名或密码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
UserDetail user = (UserDetail) authentication.getPrincipal();
|
||||||
|
|
||||||
|
// 生成 accessToken
|
||||||
|
String accessToken = TokenUtils.generator();
|
||||||
|
|
||||||
|
// 保存用户信息到缓存
|
||||||
|
tokenStoreCache.saveUser(accessToken, user);
|
||||||
|
|
||||||
|
return new SysTokenVO(accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysTokenVO loginByMobile(SysMobileLoginVO login) {
|
||||||
|
Authentication authentication;
|
||||||
|
try {
|
||||||
|
// 用户认证
|
||||||
|
authentication = authenticationManager.authenticate(
|
||||||
|
new MobileAuthenticationToken(login.getMobile(), login.getCode()));
|
||||||
|
} catch (BadCredentialsException e) {
|
||||||
|
throw new FastException("手机号或验证码错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
UserDetail user = (UserDetail) authentication.getPrincipal();
|
||||||
|
|
||||||
|
// 生成 accessToken
|
||||||
|
String accessToken = TokenUtils.generator();
|
||||||
|
|
||||||
|
// 保存用户信息到缓存
|
||||||
|
tokenStoreCache.saveUser(accessToken, user);
|
||||||
|
|
||||||
|
return new SysTokenVO(accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendCode(String mobile) {
|
||||||
|
// 生成6位验证码
|
||||||
|
String code = RandomUtil.randomNumbers(6);
|
||||||
|
|
||||||
|
SysUserVO user = sysUserService.getByMobile(mobile);
|
||||||
|
if (user == null) {
|
||||||
|
throw new FastException("手机号未注册");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送短信
|
||||||
|
smsApi.sendCode(mobile, "code", code);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logout(String accessToken) {
|
||||||
|
// 用户信息
|
||||||
|
UserDetail user = tokenStoreCache.getUser(accessToken);
|
||||||
|
|
||||||
|
// 删除用户信息
|
||||||
|
tokenStoreCache.deleteUser(accessToken);
|
||||||
|
|
||||||
|
// 保存登录日志
|
||||||
|
sysLogLoginService.save(user.getUsername(), Constant.SUCCESS, LoginOperationEnum.LOGOUT_SUCCESS.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package net.maku.system.service.impl;
|
package net.maku.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.UUID;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.wf.captcha.SpecCaptcha;
|
import com.wf.captcha.SpecCaptcha;
|
||||||
import com.wf.captcha.base.Captcha;
|
import com.wf.captcha.base.Captcha;
|
||||||
|
|
@ -7,6 +8,7 @@ import lombok.AllArgsConstructor;
|
||||||
import net.maku.framework.common.cache.RedisCache;
|
import net.maku.framework.common.cache.RedisCache;
|
||||||
import net.maku.framework.common.cache.RedisKeys;
|
import net.maku.framework.common.cache.RedisKeys;
|
||||||
import net.maku.system.service.SysCaptchaService;
|
import net.maku.system.service.SysCaptchaService;
|
||||||
|
import net.maku.system.vo.SysCaptchaVO;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -20,17 +22,26 @@ public class SysCaptchaServiceImpl implements SysCaptchaService {
|
||||||
private final RedisCache redisCache;
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generate(String key) {
|
public SysCaptchaVO generate() {
|
||||||
|
// 生成验证码key
|
||||||
|
String key = UUID.randomUUID().toString();
|
||||||
|
|
||||||
// 生成验证码
|
// 生成验证码
|
||||||
SpecCaptcha captcha = new SpecCaptcha(150, 40);
|
SpecCaptcha captcha = new SpecCaptcha(150, 40);
|
||||||
captcha.setLen(5);
|
captcha.setLen(5);
|
||||||
captcha.setCharType(Captcha.TYPE_DEFAULT);
|
captcha.setCharType(Captcha.TYPE_DEFAULT);
|
||||||
|
String image = captcha.toBase64();
|
||||||
|
|
||||||
// 保存到缓存
|
// 保存到缓存
|
||||||
key = RedisKeys.getCaptchaKey(key);
|
String redisKey = RedisKeys.getCaptchaKey(key);
|
||||||
redisCache.set(key, captcha.text(), 300);
|
redisCache.set(redisKey, captcha.text(), 300);
|
||||||
|
|
||||||
return captcha.toBase64();
|
// 封装返回数据
|
||||||
|
SysCaptchaVO captchaVO = new SysCaptchaVO();
|
||||||
|
captchaVO.setKey(key);
|
||||||
|
captchaVO.setImage(image);
|
||||||
|
|
||||||
|
return captchaVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -43,11 +54,7 @@ public class SysCaptchaServiceImpl implements SysCaptchaService {
|
||||||
String captcha = getCache(key);
|
String captcha = getCache(key);
|
||||||
|
|
||||||
// 效验成功
|
// 效验成功
|
||||||
if (code.equalsIgnoreCase(captcha)) {
|
return code.equalsIgnoreCase(captcha);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCache(String key) {
|
private String getCache(String key) {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,17 @@
|
||||||
package net.maku.security.service;
|
package net.maku.system.service.impl;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import net.maku.framework.security.user.UserDetail;
|
import net.maku.framework.security.user.UserDetail;
|
||||||
import net.maku.system.convert.SysUserConvert;
|
import net.maku.system.convert.SysUserConvert;
|
||||||
import net.maku.system.dao.SysRoleDao;
|
import net.maku.system.dao.SysRoleDao;
|
||||||
import net.maku.system.dao.SysRoleDataScopeDao;
|
import net.maku.system.dao.SysRoleDataScopeDao;
|
||||||
import net.maku.system.dao.SysUserDao;
|
|
||||||
import net.maku.system.entity.SysUserEntity;
|
import net.maku.system.entity.SysUserEntity;
|
||||||
import net.maku.system.enums.DataScopeEnum;
|
import net.maku.system.enums.DataScopeEnum;
|
||||||
import net.maku.system.enums.UserStatusEnum;
|
import net.maku.system.enums.UserStatusEnum;
|
||||||
import net.maku.system.service.SysMenuService;
|
import net.maku.system.service.SysMenuService;
|
||||||
import net.maku.system.service.SysOrgService;
|
import net.maku.system.service.SysOrgService;
|
||||||
|
import net.maku.system.service.SysUserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -21,26 +19,20 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserDetailsService
|
* 用户 UserDetails 信息
|
||||||
*
|
*
|
||||||
* @author 阿沐 babamu@126.com
|
* @author 阿沐 babamu@126.com
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class FastUserDetailsService implements UserDetailsService {
|
public class SysUserDetailsServiceImpl implements SysUserDetailsService {
|
||||||
private final SysMenuService sysMenuService;
|
private final SysMenuService sysMenuService;
|
||||||
private final SysOrgService sysOrgService;
|
private final SysOrgService sysOrgService;
|
||||||
private final SysUserDao sysUserDao;
|
|
||||||
private final SysRoleDao sysRoleDao;
|
private final SysRoleDao sysRoleDao;
|
||||||
private final SysRoleDataScopeDao sysRoleDataScopeDao;
|
private final SysRoleDataScopeDao sysRoleDataScopeDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails getUserDetails(SysUserEntity userEntity) {
|
||||||
SysUserEntity userEntity = sysUserDao.getByUsername(username);
|
|
||||||
if (userEntity == null) {
|
|
||||||
throw new UsernameNotFoundException("用户名或密码错误");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转换成UserDetail对象
|
// 转换成UserDetail对象
|
||||||
UserDetail userDetail = SysUserConvert.INSTANCE.convertDetail(userEntity);
|
UserDetail userDetail = SysUserConvert.INSTANCE.convertDetail(userEntity);
|
||||||
|
|
||||||
|
|
@ -91,5 +83,4 @@ public class FastUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -11,10 +11,10 @@ import net.maku.system.dao.SysUserDao;
|
||||||
import net.maku.system.entity.SysUserEntity;
|
import net.maku.system.entity.SysUserEntity;
|
||||||
import net.maku.system.enums.SuperAdminEnum;
|
import net.maku.system.enums.SuperAdminEnum;
|
||||||
import net.maku.system.query.SysRoleUserQuery;
|
import net.maku.system.query.SysRoleUserQuery;
|
||||||
|
import net.maku.system.query.SysUserQuery;
|
||||||
import net.maku.system.service.SysUserPostService;
|
import net.maku.system.service.SysUserPostService;
|
||||||
import net.maku.system.service.SysUserRoleService;
|
import net.maku.system.service.SysUserRoleService;
|
||||||
import net.maku.system.service.SysUserService;
|
import net.maku.system.service.SysUserService;
|
||||||
import net.maku.system.query.SysUserQuery;
|
|
||||||
import net.maku.system.vo.SysUserVO;
|
import net.maku.system.vo.SysUserVO;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
@ -49,7 +49,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||||
return new PageResult<>(SysUserConvert.INSTANCE.convertList(list), page.getTotal());
|
return new PageResult<>(SysUserConvert.INSTANCE.convertList(list), page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> getParams(SysUserQuery query){
|
private Map<String, Object> getParams(SysUserQuery query) {
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.put("username", query.getUsername());
|
params.put("username", query.getUsername());
|
||||||
params.put("mobile", query.getMobile());
|
params.put("mobile", query.getMobile());
|
||||||
|
|
@ -62,7 +62,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void save(SysUserVO vo) {
|
public void save(SysUserVO vo) {
|
||||||
|
|
@ -71,13 +70,13 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||||
|
|
||||||
// 判断用户名是否存在
|
// 判断用户名是否存在
|
||||||
SysUserEntity user = baseMapper.getByUsername(entity.getUsername());
|
SysUserEntity user = baseMapper.getByUsername(entity.getUsername());
|
||||||
if(user != null) {
|
if (user != null) {
|
||||||
throw new FastException("用户名已经存在");
|
throw new FastException("用户名已经存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断手机号是否存在
|
// 判断手机号是否存在
|
||||||
user = baseMapper.getByMobile(entity.getMobile());
|
user = baseMapper.getByMobile(entity.getMobile());
|
||||||
if(user != null) {
|
if (user != null) {
|
||||||
throw new FastException("手机号已经存在");
|
throw new FastException("手机号已经存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,13 +96,13 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||||
|
|
||||||
// 判断用户名是否存在
|
// 判断用户名是否存在
|
||||||
SysUserEntity user = baseMapper.getByUsername(entity.getUsername());
|
SysUserEntity user = baseMapper.getByUsername(entity.getUsername());
|
||||||
if(user != null && !user.getId().equals(entity.getId())) {
|
if (user != null && !user.getId().equals(entity.getId())) {
|
||||||
throw new FastException("用户名已经存在");
|
throw new FastException("用户名已经存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断手机号是否存在
|
// 判断手机号是否存在
|
||||||
user = baseMapper.getByMobile(entity.getMobile());
|
user = baseMapper.getByMobile(entity.getMobile());
|
||||||
if(user != null && !user.getId().equals(entity.getId())) {
|
if (user != null && !user.getId().equals(entity.getId())) {
|
||||||
throw new FastException("手机号已经存在");
|
throw new FastException("手机号已经存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,6 +129,13 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SysUserVO getByMobile(String mobile) {
|
||||||
|
SysUserEntity user = baseMapper.getByMobile(mobile);
|
||||||
|
|
||||||
|
return SysUserConvert.INSTANCE.convert(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updatePassword(Long id, String newPassword) {
|
public void updatePassword(Long id, String newPassword) {
|
||||||
// 修改密码
|
// 修改密码
|
||||||
SysUserEntity user = getById(id);
|
SysUserEntity user = getById(id);
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ import lombok.Data;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户登录
|
* 账号登录
|
||||||
*
|
*
|
||||||
* @author 阿沐 babamu@126.com
|
* @author 阿沐 babamu@126.com
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "用户登录")
|
@Schema(description = "账号登录")
|
||||||
public class SysLoginVO implements Serializable {
|
public class SysAccountLoginVO implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Schema(description = "用户名")
|
@Schema(description = "用户名")
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.maku.system.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片验证码
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "图片验证码")
|
||||||
|
public class SysCaptchaVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "key")
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
@Schema(description = "image base64")
|
||||||
|
private String image;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.maku.system.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号登录
|
||||||
|
*
|
||||||
|
* @author 阿沐 babamu@126.com
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "手机号登录")
|
||||||
|
public class SysMobileLoginVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "手机号")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@Schema(description = "验证码")
|
||||||
|
private String code;
|
||||||
|
}
|
||||||
|
|
@ -2,4 +2,6 @@ auth:
|
||||||
ignore_urls:
|
ignore_urls:
|
||||||
- /sys/auth/captcha
|
- /sys/auth/captcha
|
||||||
- /sys/auth/login
|
- /sys/auth/login
|
||||||
|
- /sys/auth/send/code
|
||||||
|
- /sys/auth/mobile
|
||||||
- /upload/**
|
- /upload/**
|
||||||
Loading…
Reference in New Issue
Block a user