diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/AppPasswordAuthStrategy.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/AppPasswordAuthStrategy.java new file mode 100644 index 0000000..e87fcf5 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/AppPasswordAuthStrategy.java @@ -0,0 +1,122 @@ +package com.fuyuanshen.web.service.impl; + +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.fuyuanshen.app.domain.AppUser; +import com.fuyuanshen.app.domain.vo.AppUserVo; +import com.fuyuanshen.app.mapper.AppUserMapper; +import com.fuyuanshen.app.service.AppLoginService; +import com.fuyuanshen.common.core.constant.Constants; +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.constant.SystemConstants; +import com.fuyuanshen.common.core.domain.model.AppLoginUser; +import com.fuyuanshen.common.core.domain.model.PasswordLoginBody; +import com.fuyuanshen.common.core.enums.LoginType; +import com.fuyuanshen.common.core.exception.user.CaptchaException; +import com.fuyuanshen.common.core.exception.user.CaptchaExpireException; +import com.fuyuanshen.common.core.exception.user.UserException; +import com.fuyuanshen.common.core.utils.MessageUtils; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.core.utils.ValidatorUtils; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.common.satoken.utils.AppLoginHelper; +import com.fuyuanshen.common.satoken.utils.LoginHelper; +import com.fuyuanshen.common.tenant.helper.TenantHelper; +import com.fuyuanshen.common.web.config.properties.CaptchaProperties; +import com.fuyuanshen.system.domain.vo.SysClientVo; +import com.fuyuanshen.web.domain.vo.LoginVo; +import com.fuyuanshen.web.service.IAuthStrategy; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 密码认证策略 + * + * @author Michelle.Chung + */ +@Slf4j +@Service("appPassword" + IAuthStrategy.BASE_NAME) +@RequiredArgsConstructor +public class AppPasswordAuthStrategy implements IAuthStrategy { + + private final CaptchaProperties captchaProperties; + private final AppLoginService loginService; + private final AppUserMapper appUserMapper; + @Override + public LoginVo login(String body, SysClientVo client) { + PasswordLoginBody loginBody = JsonUtils.parseObject(body, PasswordLoginBody.class); + ValidatorUtils.validate(loginBody); + String tenantId = loginBody.getTenantId(); + String username = loginBody.getUsername(); + String password = loginBody.getPassword(); + String code = loginBody.getCode(); + String uuid = loginBody.getUuid(); + +// boolean captchaEnabled = captchaProperties.getEnable(); +// // 验证码开关 +// if (captchaEnabled) { +// validateCaptcha(tenantId, username, code, uuid); +// } + AppLoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { + AppUserVo user = loadUserByUsername(username); + loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !password.equals(user.getPassword())); + // 此处可根据登录用户的数据不同 自行创建 loginUser + return loginService.buildLoginUser(user); + }); + loginUser.setClientKey(client.getClientKey()); + loginUser.setDeviceType(client.getDeviceType()); + SaLoginParameter model = new SaLoginParameter(); + model.setDeviceType(client.getDeviceType()); + // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 + // 例如: 后台用户30分钟过期 app用户1天过期 + model.setTimeout(client.getTimeout()); + model.setActiveTimeout(client.getActiveTimeout()); + model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId()); + // 生成token + AppLoginHelper.login(loginUser, model); + + LoginVo loginVo = new LoginVo(); + loginVo.setAccessToken(StpUtil.getTokenValue()); + loginVo.setExpireIn(StpUtil.getTokenTimeout()); + loginVo.setClientId(client.getClientId()); + return loginVo; + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + */ + private void validateCaptcha(String tenantId, String username, String code, String uuid) { + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.blankToDefault(uuid, ""); + String captcha = RedisUtils.getCacheObject(verifyKey); + RedisUtils.deleteObject(verifyKey); + if (captcha == null) { + loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) { + loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")); + throw new CaptchaException(); + } + } + + private AppUserVo loadUserByUsername(String username) { + AppUserVo user = appUserMapper.selectVoOne(new LambdaQueryWrapper().eq(AppUser::getUserName, username)); + if (ObjectUtil.isNull(user)) { + log.info("登录用户:{} 不存在.", username); + throw new UserException("user.not.exists", username); + } else if (SystemConstants.DISABLE.equals(user.getStatus())) { + log.info("登录用户:{} 已被停用.", username); + throw new UserException("user.blocked", username); + } + return user; + } + +} diff --git a/fys-admin/src/main/resources/application.yml b/fys-admin/src/main/resources/application.yml index 3744835..f550a10 100644 --- a/fys-admin/src/main/resources/application.yml +++ b/fys-admin/src/main/resources/application.yml @@ -1,7 +1,7 @@ # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 - port: 8000 + port: 8001 servlet: # 应用的访问路径 context-path: /