从0开始搭建后台管理系统,这是No21。上一篇我们讲到了:请求参数校验validation,这一节,我们来实现登录。
暂时放弃Mybatis-plus,拥抱Mybatis-flex版本。
以下是登录注册的功能:
package cn.lovecto.yuen.system.web.login;
import java.net.URL;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.NotLoginException;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.lovacto.framework.tenant.utis.TenantHelper;
import cn.lovecto.yuen.common.constant.UserConstants;
import cn.lovecto.yuen.common.domain.Result;
import cn.lovecto.yuen.common.utils.JsonUtils;
import cn.lovecto.yuen.common.utils.MessageUtils;
import cn.lovecto.yuen.common.utils.StreamUtils;
import cn.lovecto.yuen.common.utils.ValidatorUtils;
import cn.lovecto.yuen.framework.satoken.utils.LoginHelper;
import cn.lovecto.yuen.framework.web.core.BaseController;
import cn.lovecto.yuen.system.api.ISysClientApi;
import cn.lovecto.yuen.system.api.ISysLoginApi;
import cn.lovecto.yuen.system.api.ISysTenantApi;
import cn.lovecto.yuen.system.api.domain.bo.LoginBo;
import cn.lovecto.yuen.system.api.domain.bo.RegisterBo;
import cn.lovecto.yuen.system.api.domain.vo.LoginTenantVo;
import cn.lovecto.yuen.system.api.domain.vo.LoginVo;
import cn.lovecto.yuen.system.api.domain.vo.SysClientVo;
import cn.lovecto.yuen.system.api.domain.vo.TenantSimpleVo;
import cn.lovecto.yuen.system.auth.IAuthStrategy;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@RestController
public class LoginController extends BaseController{
private static ISysClientApi clientApi;
private static ISysTenantApi tenantApi;
private static ISysLoginApi loginApi;
/**
* 登录方法
*
* @param body 登录信息
* @return 结果
*/
@SaIgnore
@PostMapping("/login")
public Result<LoginVo> login(@RequestBody String body) {
LoginBo loginBody = JsonUtils.parseObject(body, LoginBo.class);
ValidatorUtils.validate(loginBody);
// 授权类型和客户端id
String clientId = loginBody.getClientId();
String grantType = loginBody.getGrantType();
SysClientVo clientVo = clientApi.getByClientId(clientId);
// 查询不到 client 或 client 内不包含 grantType
if (ObjectUtil.isNull(clientVo) || !StringUtils.contains(clientVo.getGrantType(), grantType)) {
log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
return Result.error(MessageUtils.message("auth.grant.type.error"));
} else if (!UserConstants.NORMAL.equals(clientVo.getStatus())) {
return Result.error(MessageUtils.message("auth.grant.type.blocked"));
}
if(StringUtils.isEmpty(clientVo.getAuthPathList())) {
log.info("客户端id: {} 授权访问列表为空!.", clientId);
return Result.error(MessageUtils.message("no.permission"));
}
// 校验租户
tenantApi.checkTenant(loginBody.getTenantId());
// 登录
LoginVo loginVo = IAuthStrategy.login(body, clientVo, grantType);
//TODO 登录成功后做的事情
return Result.success(loginVo);
}
/**
* 登出方法
*/
@PostMapping("logout")
public Result<Void> logout() {
loginApi.logout();
return Result.success();
}
/**
* 用户注册
*/
@SaIgnore
@PostMapping("register")
public Result<Void> register(@RequestBody RegisterBo registerBody) {
loginApi.register(registerBody);
return Result.success();
}
/**
* 登录页面租户下拉框
*
* @return 租户列表
*/
@SaIgnore
@GetMapping("/tenant/list")
public Result<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
// 返回对象
LoginTenantVo result = new LoginTenantVo();
boolean enable = TenantHelper.isEnable();
result.setTenantEnabled(enable);
// 如果未开启租户这直接返回
if (!enable) {
return Result.success(result);
}
List<TenantSimpleVo> voList = tenantApi.querySimpleList();
try {
// 如果只超管返回所有租户
if (LoginHelper.isSuperAdmin()) {
result.setVoList(voList);
return Result.success(result);
}
} catch (NotLoginException ignored) {
}
// 获取域名
String host;
String referer = request.getHeader("referer");
if (StringUtils.isNotBlank(referer)) {
// 这里从referer中取值是为了本地使用hosts添加虚拟域名,方便本地环境调试
host = referer.split("//")[1].split("/")[0];
} else {
host = new URL(request.getRequestURL().toString()).getHost();
}
// 根据域名进行筛选
List<TenantSimpleVo> list = StreamUtils.filter(voList, vo ->
StringUtils.equals(vo.getDomain(), host));
result.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
return Result.success(result);
}
}
LoveCTO

