|
|
|
@ -7,6 +7,7 @@
|
|
|
|
|
*
|
|
|
|
|
* 版权所有,侵权必究!
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package com.yami.shop.admin.controller;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
@ -43,6 +44,8 @@ import java.util.Set;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 后台登录相关的控制器类,主要处理管理员登录的逻辑,包括验证码校验、用户信息验证、密码验证以及生成和返回登录后的token等操作。
|
|
|
|
|
*
|
|
|
|
|
* @author FrozenWatermelon
|
|
|
|
|
* @date 2020/6/30
|
|
|
|
|
*/
|
|
|
|
@ -50,51 +53,72 @@ import java.util.stream.Collectors;
|
|
|
|
|
@Tag(name = "登录")
|
|
|
|
|
public class AdminLoginController {
|
|
|
|
|
|
|
|
|
|
// 注入TokenStore,用于存储和获取用户登录相关的token信息,比如生成token、从存储中获取token相关数据等操作。
|
|
|
|
|
@Autowired
|
|
|
|
|
private TokenStore tokenStore;
|
|
|
|
|
|
|
|
|
|
// 注入SysUserService,用于与系统用户相关的数据库操作,比如根据用户名查询用户信息等。
|
|
|
|
|
@Autowired
|
|
|
|
|
private SysUserService sysUserService;
|
|
|
|
|
|
|
|
|
|
// 注入SysMenuService,用于与系统菜单相关的数据库操作,例如查询系统菜单列表等,此处主要用于获取权限相关信息。
|
|
|
|
|
@Autowired
|
|
|
|
|
private SysMenuService sysMenuService;
|
|
|
|
|
|
|
|
|
|
// 注入PasswordCheckManager,用于对用户输入的密码进行合法性、安全性等方面的检查,比如验证密码是否符合规则、是否在一定时间内多次输错被限制登录等。
|
|
|
|
|
@Autowired
|
|
|
|
|
private PasswordCheckManager passwordCheckManager;
|
|
|
|
|
|
|
|
|
|
// 注入CaptchaService,用于处理验证码相关的操作,比如验证验证码是否正确、是否过期等。
|
|
|
|
|
@Autowired
|
|
|
|
|
private CaptchaService captchaService;
|
|
|
|
|
|
|
|
|
|
// 注入PasswordManager,用于对密码进行解密等相关操作,比如将前端传来的加密密码进行解密,以便后续进行密码验证。
|
|
|
|
|
@Autowired
|
|
|
|
|
private PasswordManager passwordManager;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理管理员登录的接口方法,接收包含账号、密码以及验证码等信息的请求体,进行一系列登录验证操作,若验证通过则返回登录成功后的token信息。
|
|
|
|
|
*
|
|
|
|
|
* @param captchaAuthenticationDTO 包含了账号、密码以及验证码验证信息的请求参数对象,通过@Valid注解进行参数合法性校验。
|
|
|
|
|
* @return 返回ServerResponseEntity类型的响应结果,若登录成功则返回包含token信息的成功响应,若验证失败则返回相应的错误提示信息。
|
|
|
|
|
*/
|
|
|
|
|
@PostMapping("/adminLogin")
|
|
|
|
|
@Operation(summary = "账号密码 + 验证码登录(用于后台登录)" , description = "通过账号/手机号/用户名密码登录")
|
|
|
|
|
@Operation(summary = "账号密码 + 验证码登录(用于后台登录)", description = "通过账号/手机号/用户名密码登录")
|
|
|
|
|
public ServerResponseEntity<?> login(
|
|
|
|
|
@Valid @RequestBody CaptchaAuthenticationDTO captchaAuthenticationDTO) {
|
|
|
|
|
|
|
|
|
|
// 登陆后台登录需要再校验一遍验证码
|
|
|
|
|
// 创建CaptchaVO对象,用于传递给验证码服务进行验证,将前端传来的验证码验证信息设置进去。
|
|
|
|
|
CaptchaVO captchaVO = new CaptchaVO();
|
|
|
|
|
captchaVO.setCaptchaVerification(captchaAuthenticationDTO.getCaptchaVerification());
|
|
|
|
|
// 调用验证码服务的验证方法,传入CaptchaVO对象,获取验证结果响应模型。
|
|
|
|
|
ResponseModel response = captchaService.verification(captchaVO);
|
|
|
|
|
// 如果验证不成功,即验证码有误或者已过期,返回相应的错误提示信息给前端。
|
|
|
|
|
if (!response.isSuccess()) {
|
|
|
|
|
return ServerResponseEntity.showFailMsg("验证码有误或已过期");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据用户名从数据库中查询系统用户信息,如果未查询到用户,说明账号不存在,抛出相应的异常提示账号或密码不正确。
|
|
|
|
|
SysUser sysUser = sysUserService.getByUserName(captchaAuthenticationDTO.getUserName());
|
|
|
|
|
if (sysUser == null) {
|
|
|
|
|
throw new YamiShopBindException("账号或密码不正确");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 半小时内密码输入错误十次,已限制登录30分钟
|
|
|
|
|
// 先对前端传来的密码进行解密操作,以便后续与数据库中存储的密码进行比对验证。
|
|
|
|
|
String decryptPassword = passwordManager.decryptPassword(captchaAuthenticationDTO.getPassWord());
|
|
|
|
|
passwordCheckManager.checkPassword(SysTypeEnum.ADMIN,captchaAuthenticationDTO.getUserName(), decryptPassword, sysUser.getPassword());
|
|
|
|
|
// 调用密码检查管理器,传入系统类型、用户名、解密后的密码以及数据库中存储的用户密码,进行密码验证,若不符合规则会抛出相应异常。
|
|
|
|
|
passwordCheckManager.checkPassword(SysTypeEnum.ADMIN, captchaAuthenticationDTO.getUserName(), decryptPassword, sysUser.getPassword());
|
|
|
|
|
|
|
|
|
|
// 不是店铺超级管理员,并且是禁用状态,无法登录
|
|
|
|
|
if (Objects.equals(sysUser.getStatus(),0)) {
|
|
|
|
|
if (Objects.equals(sysUser.getStatus(), 0)) {
|
|
|
|
|
// 若用户状态为禁用(这里假设状态0表示禁用),抛出异常提示未找到此用户信息(此处实际意思应该是用户不可用)。
|
|
|
|
|
// 未找到此用户信息
|
|
|
|
|
throw new YamiShopBindException("未找到此用户信息");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建用于存储在token中的用户信息对象,用于后续生成token以及传递给前端展示相关用户信息。
|
|
|
|
|
UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
|
|
|
|
|
userInfoInToken.setUserId(String.valueOf(sysUser.getUserId()));
|
|
|
|
|
userInfoInToken.setSysType(SysTypeEnum.ADMIN.value());
|
|
|
|
@ -102,23 +126,35 @@ public class AdminLoginController {
|
|
|
|
|
userInfoInToken.setPerms(getUserPermissions(sysUser.getUserId()));
|
|
|
|
|
userInfoInToken.setNickName(sysUser.getUsername());
|
|
|
|
|
userInfoInToken.setShopId(sysUser.getShopId());
|
|
|
|
|
// 存储token返回vo
|
|
|
|
|
|
|
|
|
|
// 调用token存储服务,将用户信息存储并生成token相关信息,获取包含token等详细信息的TokenInfoVO对象,然后返回登录成功的响应结果给前端,包含了token信息。
|
|
|
|
|
TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken);
|
|
|
|
|
return ServerResponseEntity.success(tokenInfoVO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据用户ID获取用户的权限信息集合,根据用户是否为系统超级管理员(通过特定的ID判断)采用不同的方式获取权限信息,
|
|
|
|
|
* 最终将获取到的权限字符串列表转换为去重后的权限集合返回。
|
|
|
|
|
*
|
|
|
|
|
* @param userId 用户的ID,用于确定是哪个用户的权限信息以及判断是否为系统超级管理员。
|
|
|
|
|
* @return 返回包含用户权限信息的字符串集合,每个元素代表一个权限标识。
|
|
|
|
|
*/
|
|
|
|
|
private Set<String> getUserPermissions(Long userId) {
|
|
|
|
|
List<String> permsList;
|
|
|
|
|
|
|
|
|
|
//系统管理员,拥有最高权限
|
|
|
|
|
if(userId == Constant.SUPER_ADMIN_ID){
|
|
|
|
|
// 系统管理员,拥有最高权限
|
|
|
|
|
if (userId == Constant.SUPER_ADMIN_ID) {
|
|
|
|
|
// 如果是系统超级管理员,查询所有的系统菜单列表,获取每个菜单对应的权限字符串,组成权限列表。
|
|
|
|
|
List<SysMenu> menuList = sysMenuService.list(Wrappers.emptyWrapper());
|
|
|
|
|
permsList = menuList.stream().map(SysMenu::getPerms).collect(Collectors.toList());
|
|
|
|
|
}else{
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是系统超级管理员,调用用户服务的方法查询该用户的所有权限信息,得到权限列表。
|
|
|
|
|
permsList = sysUserService.queryAllPerms(userId);
|
|
|
|
|
}
|
|
|
|
|
return permsList.stream().flatMap((perms)->{
|
|
|
|
|
|
|
|
|
|
// 将权限列表中的每个权限字符串进行分割(假设权限字符串之间以逗号分隔),然后扁平化处理,去除重复的权限,最终收集为一个权限集合返回。
|
|
|
|
|
return permsList.stream().flatMap((perms) -> {
|
|
|
|
|
if (StrUtil.isBlank(perms)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
@ -126,4 +162,4 @@ public class AdminLoginController {
|
|
|
|
|
}
|
|
|
|
|
).collect(Collectors.toSet());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|