Bonus-Cloud/bonus-auth/src/main/java/com/bonus/auth/controller/TokenController.java

269 lines
9.9 KiB
Java

package com.bonus.auth.controller;
import com.bonus.auth.config.LoginType;
import com.bonus.auth.factory.LoginStrategyFactory;
import com.bonus.auth.form.LoginBody;
import com.bonus.auth.form.RegisterBody;
import com.bonus.auth.service.*;
import com.bonus.common.core.constant.CacheConstants;
import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.JwtUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.encryption.Sm4Utils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.redis.service.RedisService;
import com.bonus.common.security.auth.AuthUtil;
import com.bonus.common.security.service.TokenService;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.config.SystemConfig;
import com.bonus.system.api.RemoteConfigService;
import com.bonus.system.api.RemoteUserService;
import com.bonus.system.api.domain.SysUser;
import com.bonus.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* Token 控制器
* 处理登录、获取验证码、登出、刷新令牌和注册功能
*/
@RestController
@Slf4j
public class TokenController {
@Resource
private SystemConfig config;
@Autowired
private TokenService tokenService;
@Autowired
private SysLoginService sysLoginService;
@Autowired
private LoginStrategyFactory loginStrategyFactory;
@Resource
private RemoteUserService remoteUserService;
@Autowired
private SysPasswordService passwordService;
@Autowired
private PasswordValidatorService passwordValidatorService;
@Autowired
private SysRecordLogService logService;
@Autowired
private RedisService redisService;
@Resource
private RemoteConfigService configService;
@Value("${third-party-login.iws.webAppId}")
private String iwsWebAppId;
@Value("${third-party-login.iws.webUrl}")
private String iwsWebUrl;
@Value("${third-party-login.iws.h5AppId}")
private String iwsH5AppId;
@Value("${third-party-login.iws.h5Url}")
private String iwsH5Url;
@PostMapping("isAdmin")
public R<?> isAdmin(@RequestBody LoginBody form) {
if (!config.isAdmin()) {
return R.ok(false);
}
passwordValidatorService.validateLoginParameters(form.getUsername(), form.getPassword());
//通过用户名获取人员信息
R<LoginUser> userResult = remoteUserService.getUserInfo(form.getUsername(), SecurityConstants.INNER);
// 验证用户查询结果
passwordValidatorService.validateUserResult(form.getUsername(), userResult);
LoginUser userInfo = userResult.getData();
SysUser user = userInfo.getSysUser();
passwordValidatorService.validateApprovalStatus(form.getUsername(), user);
// 验证用户状态
passwordValidatorService.validateUserStatus(form.getUsername(), user);
// 验证密码
passwordService.validate(user, form.getPassword(), System.currentTimeMillis());
// 处理IP校验
passwordValidatorService.handleIpValidation(form.getUsername(), user);
if (userResult.getData() == null || R.FAIL == userResult.getCode()) {
return R.fail("登录用户不存在");
}
Set<String> roles = userResult.getData().getRoles();
return R.ok(roles.contains("admin"));
}
@PostMapping("isLogin")
public R<?> isLogin(@RequestBody LoginBody form) {
LoginStrategy strategy = loginStrategyFactory.getStrategy(form.getLoginType());
if (strategy == null) {
return R.fail("不支持的登录方式");
}
if (form.getLoginType()== LoginType.EMAIL_OTP || form.getLoginType()== LoginType.PHONE_OTP ){
form.setPassword(form.getVerificationCode());
}
LoginUser login = strategy.login(form.getUsername(), form.getPassword());
return R.ok(tokenService.isLogin(String.valueOf(login.getSysUser().getUserId())));
}
@PostMapping("login")
public R<?> login(@RequestBody LoginBody form) {
// 获取相应的登录策略
LoginStrategy strategy = loginStrategyFactory.getStrategy(form.getLoginType());
if (strategy == null) {
return R.fail("不支持的登录方式");
}
if (form.getLoginType()== LoginType.EMAIL_OTP || form.getLoginType()== LoginType.PHONE_OTP || form.getLoginType()== LoginType.CUST_PHONE_OPT){
form.setPassword(form.getVerificationCode());
}
/**对系统并发数进行判断*/
long concurrency = 100;
AjaxResult result = configService.getConfigKey("sys.backend.concurrency");
if (result.isSuccess())
{
concurrency = Long.parseLong(result.get("msg").toString());
}
Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
if (keys.size() >= concurrency){
return R.fail("当前系统用户并发数超过系统配置,请稍后再试");
}
LoginUser login = strategy.login(form.getUsername(), form.getPassword());
logService.saveLogin(form.getUsername(), "登录", "登录成功", null, "成功");
if (LoginType.CUST_PHONE_PASSWORD.equals(form.getLoginType()) || LoginType.CUST_PHONE_OPT.equals(form.getLoginType())) {
Map<String, Object> map = tokenService.createCustToken(login);
login.setToken((String) map.get("access_token"));
login.setExpireIn((Long) map.get("expires_in"));
login.setLogin((boolean) map.get("isLogin"));
login.getSysUser().setPhonenumber(Sm4Utils.custDecrypt(login.getSysUser().getPhonenumber()));
login.getSysUser().setCustName(Sm4Utils.custDecrypt(login.getSysUser().getCustName()));
return R.ok(login);
} else {
return R.ok(tokenService.createToken(login));
}
}
/**
* i皖送登录
* @return
*/
@PostMapping("iwsLogin")
public R<?> iwsLogin(@RequestBody LoginBody form) {
//获取i皖送传过来的票据
String ticket = form.getTicket();
log.info("ticket=" + ticket);
if (StringUtils.isNotEmpty(ticket)) {
LoginUser loginUser = new LoginUser();
if (form.getSysType()!=null && "1".equals(form.getSysType())){
log.info("app端登录");
//loginUser = sysLoginService.iwsH5Login(ticket,iwsH5AppId,iwsH5Url);
//h5和web端调用同一个接口
loginUser = sysLoginService.iwsWebLogin(ticket,iwsH5AppId,iwsWebUrl);
} else if (form.getSysType()!=null && "0".equals(form.getSysType())) {
loginUser = sysLoginService.iwsWebLogin(ticket,iwsWebAppId,iwsWebUrl);
}else {
throw new ServiceException("登录失败,请稍后重试");
}
logService.saveLogin(loginUser.getSysUser().getUserName(), "登录", "登录成功", null, "成功");
//生成系统token
return R.ok(tokenService.createToken(loginUser));
}
return R.fail("登录失败!");
}
/**
* 获取手机验证码
*
* @param form 登录表单
* @return 验证码发送结果
*/
@PostMapping("getPhoneCode")
public R<?> getPhoneCode(@RequestBody LoginBody form) {
return sysLoginService.getPhoneCode(form.getUsername(), form.getVerificationCodeType());
}
/**
* 用户登出
*
* @param request HTTP 请求
* @return 登出结果
*/
@PostMapping("logout")
public R<?> logout(HttpServletRequest request) {
try {
String token = SecurityUtils.getToken(request);
if (StringUtils.isNotEmpty(token)) {
String key = JwtUtils.getUserKey(token);
boolean key1 = tokenService.isKey(key);
if (key1) {
String username = JwtUtils.getUserName(token);
String userId = JwtUtils.getUserId(token);
AuthUtil.logoutByToken(token);
tokenService.delExistingToken(Long.valueOf(userId));
sysLoginService.logout(username, userId);
logService.saveLogout(username, "退出登录", "退出成功", userId, "成功");
}
return R.ok();
}
} catch (Exception e) {
log.error("登出失败: {}", e.getMessage(), e);
}
sysLoginService.logout("", "");
return R.ok();
}
/**
* 刷新令牌
*
* @param request HTTP 请求
* @return 刷新结果
*/
@PostMapping("refresh")
public R<?> refresh(HttpServletRequest request) {
try {
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser)) {
tokenService.refreshToken(loginUser);
return R.ok();
}
} catch (Exception e) {
log.error("刷新令牌失败: {}", e.getMessage(), e);
}
return R.fail("刷新令牌失败");
}
/**
* 用户注册
*
* @param registerBody 注册表单
* @return 注册结果
*/
@PostMapping("register")
public R<?> register(@RequestBody RegisterBody registerBody) {
sysLoginService.register(registerBody);
logService.saveRegister(registerBody.getUsername(), "注册", "注册成功", null, "成功");
return R.ok();
}
}