perf:请求时将通过getCurrentUserName()方法返回的对象检验用户是否非法

This commit is contained in:
曾文豪
2024-08-07 14:09:28 +08:00
parent bb38428708
commit 1ee4b4af30
27 changed files with 295 additions and 314 deletions

View File

@@ -1,11 +1,12 @@
package com.tiesheng.demo.config; package com.tiesheng.demo.config;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.tiesheng.web.pojos.RequestUserInfo; import com.tiesheng.login.pojos.RequestUserInfo;
import com.tiesheng.web.pojos.dao.CorePlatformUnique; import com.tiesheng.login.pojos.dao.CorePlatformUnique;
import com.tiesheng.web.service.TieshengWebConfigurer; import com.tiesheng.login.service.TsLoginConfigurer;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.config.GlobalConfig; import com.tiesheng.util.config.GlobalConfig;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.web.service.TieshengWebConfigurer;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -13,24 +14,28 @@ import javax.servlet.http.HttpServletResponse;
import java.util.Objects; import java.util.Objects;
@Component @Component
public class DemoWebConfigurer implements TieshengWebConfigurer { public class DemoWebConfigurer implements TieshengWebConfigurer, TsLoginConfigurer {
@Autowired @Autowired
GlobalConfig globalConfig; GlobalConfig globalConfig;
@Override @Override
public RequestUserInfo getCurrentUserName(TokenBean tokenBean) { public RequestUserInfo getCurrentUserName(TokenBean tokenBean) {
RequestUserInfo info = new RequestUserInfo(); RequestUserInfo info = new RequestUserInfo();
info.setId("1"); if (Objects.equals(tokenBean.getId(), "1")) {
info.setName("test");
return info; return info;
} }
return null;
}
@Override
public TokenBean login(CorePlatformUnique platformUnique) { public TokenBean login(CorePlatformUnique platformUnique) {
TokenBean tokenBean = null; TokenBean tokenBean = null;
if (!StrUtil.isEmpty(platformUnique.getUserId())) { if (!StrUtil.isEmpty(platformUnique.getUserId())) {
tokenBean = new TokenBean(platformUnique.getUserId(), "", globalConfig.getService()); tokenBean = new TokenBean(platformUnique.getUserId(), "", globalConfig.getService());
} else if (Objects.equals(platformUnique.getUniqueId(), "1110290049")) {
tokenBean = new TokenBean("1", "", globalConfig.getService());
tokenBean.setExtra("1110290049");
} }
return tokenBean; return tokenBean;
@@ -39,13 +44,11 @@ public class DemoWebConfigurer implements TieshengWebConfigurer {
@Override @Override
public void redirect(TokenBean bean, String to, String extra, HttpServletResponse response) { public void redirect(TokenBean bean, String to, String extra, HttpServletResponse response) {
// 默认跳转到mobile
to = StrUtil.emptyToDefault(to, "static/mobile");
bean.setEnvironmentType(to);
if (Objects.equals(bean.getEnvironmentType(), "static/mobile")) {
globalConfig.redirect("static/mobile", "/?token=" + bean.toToken(), response);
}
} }
@Override
public TsLoginConfigurer configureLogin() {
return this;
}
} }

View File

@@ -1,15 +0,0 @@
package com.tiesheng.demo.config;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class DemoWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mobile/**").addResourceLocations("classpath:/mobile/0.0.13/");
}
}

View File

@@ -1,16 +0,0 @@
package com.tiesheng.login;
import com.tiesheng.platform.PlatformAutoConfigurer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
/**
* @author hao
*/
@ComponentScan({
"com.tiesheng.login.**.*",
})
@Import(PlatformAutoConfigurer.class)
public class LoginAutoConfigurer {
}

View File

@@ -3,7 +3,10 @@ package com.tiesheng.login.config;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.tiesheng.annotation.token.TokenIgnore; import com.tiesheng.annotation.token.TokenIgnore;
import com.tiesheng.login.pojos.RequestUserInfo;
import com.tiesheng.login.service.TsLoginConfigurer;
import com.tiesheng.util.config.TsTokenConfig; import com.tiesheng.util.config.TsTokenConfig;
import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.pojos.TokenBean; import com.tiesheng.util.pojos.TokenBean;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -29,6 +32,8 @@ public class TokenWebMvcConfigurer implements WebMvcConfigurer {
@Resource @Resource
TsTokenConfig tsTokenConfig; TsTokenConfig tsTokenConfig;
@Resource
TsLoginConfigurer tsLoginConfigurer;
@Override @Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
@@ -96,8 +101,14 @@ public class TokenWebMvcConfigurer implements WebMvcConfigurer {
return true; return true;
} }
// token验证 // 验证TOKEN是否存在
tsTokenConfig.validToken(request, true); TokenBean tokenBean = tsTokenConfig.validToken(request, true);
// 验证用户是否存在
RequestUserInfo cachedUserInfo = tsLoginConfigurer.getCachedUserInfo(tokenBean);
if (cachedUserInfo == null) {
throw new ApiException("非法TOKEN请重新登录");
}
return true; return true;
} }

View File

@@ -6,13 +6,11 @@ import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.tiesheng.annotation.operation.OperationIgnore; import com.tiesheng.annotation.operation.OperationIgnore;
import com.tiesheng.annotation.token.TokenIgnore; import com.tiesheng.annotation.token.TokenIgnore;
import com.tiesheng.util.config.TsTokenConfig;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.login.pojos.CodeExtraDTO; import com.tiesheng.login.pojos.CodeExtraDTO;
import com.tiesheng.login.pojos.DoLoginInfo; import com.tiesheng.login.pojos.DoLoginInfo;
import com.tiesheng.login.pojos.UniqueIndexDTO; import com.tiesheng.login.pojos.UniqueIndexDTO;
import com.tiesheng.login.pojos.WxminiLoginVo; import com.tiesheng.login.pojos.WxminiLoginVo;
import com.tiesheng.login.service.TieshengLoginConfigurer; import com.tiesheng.login.service.CorePlatformUniqueService;
import com.tiesheng.platform.config.ding.PlatformDingConfig; import com.tiesheng.platform.config.ding.PlatformDingConfig;
import com.tiesheng.platform.config.ding.bean.DingJsapiSignature; import com.tiesheng.platform.config.ding.bean.DingJsapiSignature;
import com.tiesheng.platform.config.ding.bean.DingUserInfo; import com.tiesheng.platform.config.ding.bean.DingUserInfo;
@@ -23,8 +21,10 @@ import com.tiesheng.platform.config.wxmp.bean.WxConfigBean;
import com.tiesheng.platform.config.wxmp.bean.WxJsapiSignature; import com.tiesheng.platform.config.wxmp.bean.WxJsapiSignature;
import com.tiesheng.platform.config.wxmp.bean.WxUserInfo; import com.tiesheng.platform.config.wxmp.bean.WxUserInfo;
import com.tiesheng.util.config.GlobalConfig; import com.tiesheng.util.config.GlobalConfig;
import com.tiesheng.util.config.TsTokenConfig;
import com.tiesheng.util.exception.ApiException; import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.pojos.ApiResp; import com.tiesheng.util.pojos.ApiResp;
import com.tiesheng.util.pojos.TokenBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -49,7 +49,7 @@ public class LoginController {
@Autowired @Autowired
PlatformWxminiConfig platformWxminiConfig; PlatformWxminiConfig platformWxminiConfig;
@Autowired @Autowired
TieshengLoginConfigurer tieshengLoginConfigurer; CorePlatformUniqueService corePlatformUniqueService;
@Autowired @Autowired
GlobalConfig globalConfig; GlobalConfig globalConfig;
@Autowired @Autowired
@@ -65,13 +65,13 @@ public class LoginController {
@OperationIgnore @OperationIgnore
public void uniqueIndex(UniqueIndexDTO dto, HttpServletResponse response) { public void uniqueIndex(UniqueIndexDTO dto, HttpServletResponse response) {
if (tsTokenConfig.isValidLoginSign() && !dto.validSign()) { if (tsTokenConfig.isValidLoginSign() && !dto.validSign()) {
tieshengLoginConfigurer.onSignError(response); corePlatformUniqueService.onSignError(response);
return; return;
} }
TokenBean tokenBean = tieshengLoginConfigurer.doLogin(new DoLoginInfo("web_unique_redirect", TokenBean tokenBean = corePlatformUniqueService.login(new DoLoginInfo("web_unique_redirect",
dto.getNo(), dto.getPlatform(), dto.getInfo())); dto.getNo(), dto.getPlatform(), dto.getInfo()));
tieshengLoginConfigurer.onLoginRedirect(tokenBean, dto.getTo(), dto.getExtra(), response); corePlatformUniqueService.redirect(tokenBean, dto.getTo(), dto.getExtra(), response);
} }
@@ -84,7 +84,7 @@ public class LoginController {
@PostMapping("/unique/index") @PostMapping("/unique/index")
@OperationIgnore @OperationIgnore
public ApiResp<String> uniqueIndex(@RequestBody UniqueIndexDTO dto) { public ApiResp<String> uniqueIndex(@RequestBody UniqueIndexDTO dto) {
TokenBean tokenBean = tieshengLoginConfigurer.doLogin(new DoLoginInfo("web_unique_index", TokenBean tokenBean = corePlatformUniqueService.login(new DoLoginInfo("web_unique_index",
dto.getNo(), dto.getPlatform(), dto.getInfo())); dto.getNo(), dto.getPlatform(), dto.getInfo()));
if (tokenBean == null || StrUtil.isEmpty(tokenBean.getId())) { if (tokenBean == null || StrUtil.isEmpty(tokenBean.getId())) {
throw new ApiException("登录失败"); throw new ApiException("登录失败");
@@ -134,9 +134,9 @@ public class LoginController {
public void dingOauth2(@PathVariable String service, CodeExtraDTO dto, HttpServletResponse response) { public void dingOauth2(@PathVariable String service, CodeExtraDTO dto, HttpServletResponse response) {
DingUserSimple userSimple = platformDingConfig.getUserIdByCode(service, dto.getCode()); DingUserSimple userSimple = platformDingConfig.getUserIdByCode(service, dto.getCode());
DingUserInfo dingUserInfo = platformDingConfig.topapiV2UserGet(service, userSimple.getUserid()); DingUserInfo dingUserInfo = platformDingConfig.topapiV2UserGet(service, userSimple.getUserid());
TokenBean tokenBean = tieshengLoginConfigurer.doLogin(new DoLoginInfo(dingUserInfo.getAppId(), TokenBean tokenBean = corePlatformUniqueService.login(new DoLoginInfo(dingUserInfo.getAppId(),
dingUserInfo.getUserid(), "ding", JSON.toJSONString(dingUserInfo))); dingUserInfo.getUserid(), "ding", JSON.toJSONString(dingUserInfo)));
tieshengLoginConfigurer.onLoginRedirect(tokenBean, dto.getTo(), dto.getExtra(), response); corePlatformUniqueService.redirect(tokenBean, dto.getTo(), dto.getExtra(), response);
} }
@@ -182,9 +182,9 @@ public class LoginController {
@OperationIgnore @OperationIgnore
public void wxmpOauth2(@PathVariable String service, CodeExtraDTO dto, HttpServletResponse response) { public void wxmpOauth2(@PathVariable String service, CodeExtraDTO dto, HttpServletResponse response) {
WxUserInfo wxUserInfo = platformWxmpConfig.getOAuth2AccessToken(service, dto.getCode()); WxUserInfo wxUserInfo = platformWxmpConfig.getOAuth2AccessToken(service, dto.getCode());
TokenBean tokenBean = tieshengLoginConfigurer.doLogin(new DoLoginInfo(wxUserInfo.getAppId(), TokenBean tokenBean = corePlatformUniqueService.login(new DoLoginInfo(wxUserInfo.getAppId(),
wxUserInfo.getOpenid(), "wxmp", JSON.toJSONString(wxUserInfo))); wxUserInfo.getOpenid(), "wxmp", JSON.toJSONString(wxUserInfo)));
tieshengLoginConfigurer.onLoginRedirect(tokenBean, dto.getTo(), dto.getExtra(), response); corePlatformUniqueService.redirect(tokenBean, dto.getTo(), dto.getExtra(), response);
} }
@@ -214,7 +214,7 @@ public class LoginController {
public ApiResp<WxminiLoginVo> wxminiIndex(@PathVariable String service, String code) { public ApiResp<WxminiLoginVo> wxminiIndex(@PathVariable String service, String code) {
String openid = platformWxminiConfig.jscode2session(service, code); String openid = platformWxminiConfig.jscode2session(service, code);
WxConfigBean configBean = platformWxminiConfig.getConfigBean(service); WxConfigBean configBean = platformWxminiConfig.getConfigBean(service);
TokenBean tokenBean = tieshengLoginConfigurer.doLogin(new DoLoginInfo(configBean.getAppId(), TokenBean tokenBean = corePlatformUniqueService.login(new DoLoginInfo(configBean.getAppId(),
openid, "wxmini", "{}")); openid, "wxmini", "{}"));
WxminiLoginVo loginVo = new WxminiLoginVo(); WxminiLoginVo loginVo = new WxminiLoginVo();

View File

@@ -1,7 +1,7 @@
package com.tiesheng.web.mapper; package com.tiesheng.login.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tiesheng.web.pojos.dao.CoreLogLogin; import com.tiesheng.login.pojos.dao.CoreLogLogin;
public interface CoreLogLoginMapper extends BaseMapper<CoreLogLogin> { public interface CoreLogLoginMapper extends BaseMapper<CoreLogLogin> {
} }

View File

@@ -1,7 +1,7 @@
package com.tiesheng.web.mapper; package com.tiesheng.login.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tiesheng.web.pojos.dao.CorePlatformUnique; import com.tiesheng.login.pojos.dao.CorePlatformUnique;
public interface CorePlatformUniqueMapper extends BaseMapper<CorePlatformUnique> { public interface CorePlatformUniqueMapper extends BaseMapper<CorePlatformUnique> {
} }

View File

@@ -1,4 +1,4 @@
package com.tiesheng.web.pojos; package com.tiesheng.login.pojos;
/** /**
* 当前token的数据 * 当前token的数据

View File

@@ -1,4 +1,4 @@
package com.tiesheng.web.pojos.dao; package com.tiesheng.login.pojos.dao;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;

View File

@@ -1,4 +1,4 @@
package com.tiesheng.web.pojos.dao; package com.tiesheng.login.pojos.dao;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;

View File

@@ -0,0 +1,113 @@
package com.tiesheng.login.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.tiesheng.login.mapper.CoreLogLoginMapper;
import com.tiesheng.login.mapper.CorePlatformUniqueMapper;
import com.tiesheng.login.pojos.DoLoginInfo;
import com.tiesheng.login.pojos.RequestUserInfo;
import com.tiesheng.login.pojos.dao.CoreLogLogin;
import com.tiesheng.login.pojos.dao.CorePlatformUnique;
import com.tiesheng.util.ServletKit;
import com.tiesheng.util.config.Ip2regionConfig;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.service.TsServiceBase;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* @author hao
*/
@Service
public class CorePlatformUniqueService extends TsServiceBase<CorePlatformUniqueMapper, CorePlatformUnique> {
@Resource
CoreLogLoginMapper coreLogLoginMapper;
@Resource
Ip2regionConfig ip2regionConfig;
@Resource
TsLoginConfigurer tsLoginConfigurer;
@Transactional(rollbackFor = Exception.class)
public TokenBean login(DoLoginInfo loginInfo) {
CorePlatformUnique platformUnique = getOneByColumn("unique_id", loginInfo.getUnique());
if (platformUnique == null) {
platformUnique = new CorePlatformUnique();
platformUnique.setAppId(loginInfo.getAppId());
platformUnique.setUniqueId(loginInfo.getUnique());
}
platformUnique.setPlatform(loginInfo.getPlatform());
platformUnique.setInfo(loginInfo.getInfo());
saveOrUpdate(platformUnique);
String oldUserId = platformUnique.getUserId();
TokenBean tokenBean = tsLoginConfigurer.login(platformUnique);
if (tokenBean != null) {
// 添加登录日志
addLoginLog(platformUnique, tokenBean);
// 更新唯一值
if (!StrUtil.isEmpty(tokenBean.getId()) &&
!Objects.equals(oldUserId, tokenBean.getId())) {
platformUnique.setUserId(tokenBean.getId());
saveOrUpdate(platformUnique);
}
}
return tokenBean;
}
/**
* 授权登录回调
*
* @param bean
*/
public void redirect(TokenBean bean, String to, String extra, HttpServletResponse response) {
tsLoginConfigurer.redirect(bean, to, extra, response);
}
/**
* 签名错误的时候
*/
public void onSignError(HttpServletResponse response) {
tsLoginConfigurer.onSignError(response);
}
///////////////////////////////////////////////////////////////////////////
// 登录日志
///////////////////////////////////////////////////////////////////////////
/**
* 添加登录日志
*
* @param platformUnique
* @param tokenBean
*/
public void addLoginLog(CorePlatformUnique platformUnique, TokenBean tokenBean) {
HttpServletRequest request = ServletKit.getRequest();
String ip = ServletUtil.getClientIP(request);
CoreLogLogin login = new CoreLogLogin();
login.setUserId(tokenBean.getId());
login.setPlatform(platformUnique.getPlatform());
RequestUserInfo requestUserInfo = tsLoginConfigurer.getCachedUserInfo(tokenBean);
login.setUserName(requestUserInfo.getName());
login.setIp(ip);
login.setAddress(ip2regionConfig.search(login.getIp()));
coreLogLoginMapper.insert(login);
}
}

View File

@@ -1,36 +0,0 @@
package com.tiesheng.login.service;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.login.pojos.DoLoginInfo;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServletResponse;
/**
* @author hao
*/
@Configuration
public interface TieshengLoginConfigurer {
/**
* 执行登录
*
* @return
*/
TokenBean doLogin(DoLoginInfo loginInfo);
/**
* 授权登录回调
*
* @param bean
*/
void onLoginRedirect(TokenBean bean, String to, String extra, HttpServletResponse response);
/**
* 签名错误的时候
*/
void onSignError(HttpServletResponse response);
}

View File

@@ -0,0 +1,69 @@
package com.tiesheng.login.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.tiesheng.login.pojos.RequestUserInfo;
import com.tiesheng.login.pojos.dao.CorePlatformUnique;
import com.tiesheng.util.config.TsTokenConfig;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.service.TsCacheService;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServletResponse;
/**
* @author hao
*/
@Configuration
public interface TsLoginConfigurer {
/**
* 执行登录
*
* @return
*/
TokenBean login(CorePlatformUnique platformUnique);
/**
* 授权登录回调
*
* @param bean
*/
void redirect(TokenBean bean, String to, String extra, HttpServletResponse response);
/**
* 签名错误的时候
*/
default void onSignError(HttpServletResponse response) {
ServletUtil.write(response, "404", "text");
}
/**
* 获取当前用户的信息
*
* @param tokenBean
* @return
*/
default RequestUserInfo getCachedUserInfo(TokenBean tokenBean) {
String key = StrUtil.format(TsTokenConfig.CACHE_REQUEST_LOGIN_KEY, tokenBean.getId());
RequestUserInfo obj = TsCacheService.of().getObj(key, RequestUserInfo.class, -1);
if (obj == null) {
obj = getCurrentUserName(tokenBean);
}
if (obj != null) {
TsCacheService.of().putObj(key, obj, 30 * 60);
}
return obj;
}
/**
* 获取当前用户的姓名
*
* @return
*/
RequestUserInfo getCurrentUserName(TokenBean userId);
}

View File

@@ -1,32 +0,0 @@
package com.tiesheng.login.service.impl;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.login.pojos.DoLoginInfo;
import com.tiesheng.login.service.TieshengLoginConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServletResponse;
/**
* @author hao
*/
@Configuration
@ConditionalOnMissingBean(value = TieshengLoginConfigurer.class, ignored = DefaultLoginConfigurer.class)
public class DefaultLoginConfigurer implements TieshengLoginConfigurer {
@Override
public TokenBean doLogin(DoLoginInfo loginInfo) {
return null;
}
@Override
public void onLoginRedirect(TokenBean bean, String to, String extra, HttpServletResponse response) {
}
@Override
public void onSignError(HttpServletResponse response) {
}
}

View File

@@ -1,6 +1,24 @@
SET NAMES utf8mb4; SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for core_log_login
-- ----------------------------
CREATE TABLE `core_log_login`
(
`id` varchar(50) NOT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
`is_deleted` int(6) NOT NULL DEFAULT '0',
`user_id` varchar(50) DEFAULT NULL COMMENT '用户id',
`user_name` varchar(255) DEFAULT NULL COMMENT '用户姓名',
`platform` varchar(50) DEFAULT NULL COMMENT '登录方式',
`ip` varchar(100) DEFAULT NULL COMMENT 'ip',
`address` varchar(255) DEFAULT NULL COMMENT 'ip地址',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='日志-登录';
-- ---------------------------- -- ----------------------------
-- Table structure for core_platform_unique -- Table structure for core_platform_unique
-- ---------------------------- -- ----------------------------

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tiesheng.web.mapper.CoreLogLoginMapper"> <mapper namespace="com.tiesheng.login.mapper.CoreLogLoginMapper">
<resultMap id="BaseResultMap" type="com.tiesheng.web.pojos.dao.CoreLogLogin"> <resultMap id="BaseResultMap" type="com.tiesheng.login.pojos.dao.CoreLogLogin">
<!--@mbg.generated--> <!--@mbg.generated-->
<!--@Table core_log_login--> <!--@Table core_log_login-->
<id column="id" jdbcType="VARCHAR" property="id" /> <id column="id" jdbcType="VARCHAR" property="id" />

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tiesheng.web.mapper.CorePlatformUniqueMapper"> <mapper namespace="com.tiesheng.login.mapper.CorePlatformUniqueMapper">
<resultMap id="BaseResultMap" type="com.tiesheng.web.pojos.dao.CorePlatformUnique"> <resultMap id="BaseResultMap" type="com.tiesheng.login.pojos.dao.CorePlatformUnique">
<!--@mbg.generated--> <!--@mbg.generated-->
<!--@Table core_platform_unique--> <!--@Table core_platform_unique-->
<id column="id" jdbcType="VARCHAR" property="id" /> <id column="id" jdbcType="VARCHAR" property="id" />

View File

@@ -104,7 +104,7 @@ public class PlatformDingConfig {
* @return accessToken * @return accessToken
* @see <a href="https://open.dingtalk.com/document/orgapp-server/obtain-orgapp-token" /> * @see <a href="https://open.dingtalk.com/document/orgapp-server/obtain-orgapp-token" />
*/ */
public String getAccessToken(String service) { public synchronized String getAccessToken(String service) {
DingConfigBean dingConfigBean = getConfigBean(service); DingConfigBean dingConfigBean = getConfigBean(service);
String accessToken = TsCacheService.of().get(CACHE_ACCESS_TOKEN + dingConfigBean.getAppKey(), -1); String accessToken = TsCacheService.of().get(CACHE_ACCESS_TOKEN + dingConfigBean.getAppKey(), -1);
if (!StrUtil.isEmpty(accessToken)) { if (!StrUtil.isEmpty(accessToken)) {

View File

@@ -23,6 +23,12 @@ import java.util.Map;
@ConfigurationProperties("tiesheng.token") @ConfigurationProperties("tiesheng.token")
public class TsTokenConfig { public class TsTokenConfig {
/**
* 用户登录的KEY
*/
public static String CACHE_REQUEST_LOGIN_KEY = "request:login:{}";
/** /**
* token常量 * token常量
*/ */
@@ -79,7 +85,7 @@ public class TsTokenConfig {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
if (tokenBean == null && thrExp) { if ((tokenBean == null || StrUtil.isEmpty(tokenBean.getId())) && thrExp) {
throw new ApiException(StrUtil.isEmpty(token) ? 110 : 112, throw new ApiException(StrUtil.isEmpty(token) ? 110 : 112,
StrUtil.isEmpty(token) ? "请先登录" : "登录过期,请重新登陆"); StrUtil.isEmpty(token) ? "请先登录" : "登录过期,请重新登陆");
} }

View File

@@ -45,6 +45,16 @@ public class TsCacheService {
return tsCacheHandler.get(key, seconds); return tsCacheHandler.get(key, seconds);
} }
/**
* 获取一个缓存对象
*
* @param key
* @param tClass
* @param seconds =0时获取数据后会删除缓存<0时不改变原有缓存时间
* @param <T>
* @return
*/
public <T> T getObj(String key, Class<T> tClass, long seconds) { public <T> T getObj(String key, Class<T> tClass, long seconds) {
return JSONUtil.toBean(get(key, seconds), tClass, true); return JSONUtil.toBean(get(key, seconds), tClass, true);
} }

View File

@@ -2,8 +2,8 @@ package com.tiesheng.web;
import com.tiesheng.database.DatabaseAutoConfigurer; import com.tiesheng.database.DatabaseAutoConfigurer;
import com.tiesheng.encrypt.EncryptAutoConfigurer; import com.tiesheng.encrypt.EncryptAutoConfigurer;
import com.tiesheng.login.LoginAutoConfigurer;
import com.tiesheng.message.MessageAutoConfigurer; import com.tiesheng.message.MessageAutoConfigurer;
import com.tiesheng.platform.PlatformAutoConfigurer;
import com.tiesheng.util.UtilAutoConfigurer; import com.tiesheng.util.UtilAutoConfigurer;
import com.tiesheng.web.service.TieshengWebConfigurer; import com.tiesheng.web.service.TieshengWebConfigurer;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@@ -20,9 +20,9 @@ import java.lang.annotation.*;
UtilAutoConfigurer.class, UtilAutoConfigurer.class,
MessageAutoConfigurer.class, MessageAutoConfigurer.class,
WebAutoConfigurer.class, WebAutoConfigurer.class,
LoginAutoConfigurer.class,
DatabaseAutoConfigurer.class, DatabaseAutoConfigurer.class,
EncryptAutoConfigurer.class, EncryptAutoConfigurer.class,
PlatformAutoConfigurer.class,
}) })
public @interface EnableTieshengWeb { public @interface EnableTieshengWeb {

View File

@@ -10,7 +10,8 @@ import org.springframework.context.annotation.ComponentScan;
@ComponentScan({ @ComponentScan({
"com.tiesheng.web.**.*", "com.tiesheng.web.**.*",
"com.tiesheng.role.**.*", "com.tiesheng.role.**.*",
"com.tiesheng.login.**.*",
}) })
@MapperScan(value = {"com.tiesheng.web.mapper", "com.tiesheng.role.mapper"}) @MapperScan(value = {"com.tiesheng.web.mapper", "com.tiesheng.role.mapper", "com.tiesheng.login.mapper"})
public class WebAutoConfigurer { public class WebAutoConfigurer {
} }

View File

@@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tiesheng.util.pojos.ApiResp; import com.tiesheng.util.pojos.ApiResp;
import com.tiesheng.util.pojos.PageDTO; import com.tiesheng.util.pojos.PageDTO;
import com.tiesheng.web.pojos.dao.CoreLogApi; import com.tiesheng.web.pojos.dao.CoreLogApi;
import com.tiesheng.web.pojos.dao.CoreLogLogin; import com.tiesheng.login.pojos.dao.CoreLogLogin;
import com.tiesheng.web.pojos.dao.CoreLogOperation; import com.tiesheng.web.pojos.dao.CoreLogOperation;
import com.tiesheng.web.pojos.dao.CoreLogProcess; import com.tiesheng.web.pojos.dao.CoreLogProcess;
import com.tiesheng.web.pojos.vo.ProcessDetailVo; import com.tiesheng.web.pojos.vo.ProcessDetailVo;

View File

@@ -5,30 +5,24 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tiesheng.util.ServletKit; import com.tiesheng.login.mapper.CoreLogLoginMapper;
import com.tiesheng.util.config.Ip2regionConfig; import com.tiesheng.login.pojos.RequestUserInfo;
import com.tiesheng.util.exception.ApiException; import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.pojos.TokenBean; import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.service.TsServiceBase; import com.tiesheng.util.service.TsServiceBase;
import com.tiesheng.web.mapper.CoreLogApiMapper; import com.tiesheng.web.mapper.CoreLogApiMapper;
import com.tiesheng.web.mapper.CoreLogLoginMapper;
import com.tiesheng.web.mapper.CoreLogOperationMapper; import com.tiesheng.web.mapper.CoreLogOperationMapper;
import com.tiesheng.web.mapper.CoreLogProcessMapper; import com.tiesheng.web.mapper.CoreLogProcessMapper;
import com.tiesheng.web.pojos.RequestUserInfo;
import com.tiesheng.web.pojos.dao.CoreLogLogin;
import com.tiesheng.web.pojos.dao.CoreLogOperation; import com.tiesheng.web.pojos.dao.CoreLogOperation;
import com.tiesheng.web.pojos.dao.CoreLogProcess; import com.tiesheng.web.pojos.dao.CoreLogProcess;
import com.tiesheng.web.pojos.dao.CorePlatformUnique;
import com.tiesheng.web.pojos.vo.ProcessDetailVo; import com.tiesheng.web.pojos.vo.ProcessDetailVo;
import com.tiesheng.web.util.ProcessImportConsumer; import com.tiesheng.web.util.ProcessImportConsumer;
import com.tiesheng.web.util.ProcessSyncConsumer; import com.tiesheng.web.util.ProcessSyncConsumer;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -50,8 +44,6 @@ public class CoreLogService extends TsServiceBase<CoreLogOperationMapper, CoreLo
@Autowired @Autowired
CoreLogApiMapper coreLogApiMapper; CoreLogApiMapper coreLogApiMapper;
@Autowired @Autowired
Ip2regionConfig ip2regionConfig;
@Autowired
CoreLogProcessMapper coreLogProcessMapper; CoreLogProcessMapper coreLogProcessMapper;
public CoreLogLoginMapper getLogLoginMapper() { public CoreLogLoginMapper getLogLoginMapper() {
@@ -184,12 +176,12 @@ public class CoreLogService extends TsServiceBase<CoreLogOperationMapper, CoreLo
*/ */
public void addOperationLog(TokenBean tokenBean, String title, String subject, Object params) { public void addOperationLog(TokenBean tokenBean, String title, String subject, Object params) {
RequestUserInfo requestUserInfo = null; if (tokenBean == null || StrUtil.isEmpty(tokenBean.getId())) {
if (tokenBean != null && !StrUtil.isEmpty(tokenBean.getId())) { return;
requestUserInfo = tieshengWebConfigurer.getCurrentUserName(tokenBean);
} }
RequestUserInfo requestUserInfo = tieshengWebConfigurer.configureLogin().getCachedUserInfo(tokenBean);
if (requestUserInfo == null) { if (requestUserInfo == null) {
requestUserInfo = new RequestUserInfo(); return;
} }
CoreLogOperation operation = new CoreLogOperation(); CoreLogOperation operation = new CoreLogOperation();
@@ -210,34 +202,7 @@ public class CoreLogService extends TsServiceBase<CoreLogOperationMapper, CoreLo
cacheOperations.clear(); cacheOperations.clear();
} }
} }
} }
///////////////////////////////////////////////////////////////////////////
// 登录日志
///////////////////////////////////////////////////////////////////////////
/**
* 添加登录日志
*
* @param platformUnique
* @param tokenBean
*/
public void addLoginLog(CorePlatformUnique platformUnique, TokenBean tokenBean) {
HttpServletRequest request = ServletKit.getRequest();
String ip = ServletUtil.getClientIP(request);
CoreLogLogin login = new CoreLogLogin();
login.setUserId(tokenBean.getId());
login.setPlatform(platformUnique.getPlatform());
RequestUserInfo requestUserInfo = tieshengWebConfigurer.getCurrentUserName(tokenBean);
login.setUserName(requestUserInfo.getName());
login.setIp(ip);
login.setAddress(ip2regionConfig.search(login.getIp()));
coreLogLoginMapper.insert(login);
}
} }

View File

@@ -1,72 +0,0 @@
package com.tiesheng.web.service;
import cn.hutool.core.util.StrUtil;
import com.tiesheng.web.mapper.CorePlatformUniqueMapper;
import com.tiesheng.web.pojos.dao.CorePlatformUnique;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.login.pojos.DoLoginInfo;
import com.tiesheng.login.service.TieshengLoginConfigurer;
import com.tiesheng.util.service.TsServiceBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* @author hao
*/
@Service
public class CorePlatformUniqueService extends TsServiceBase<CorePlatformUniqueMapper, CorePlatformUnique> implements TieshengLoginConfigurer {
@Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@Autowired
CoreLogService coreLogService;
@Override
@Transactional(rollbackFor = Exception.class)
public TokenBean doLogin(DoLoginInfo loginInfo) {
CorePlatformUnique platformUnique = getOneByColumn("unique_id", loginInfo.getUnique());
if (platformUnique == null) {
platformUnique = new CorePlatformUnique();
platformUnique.setAppId(loginInfo.getAppId());
platformUnique.setUniqueId(loginInfo.getUnique());
}
platformUnique.setPlatform(loginInfo.getPlatform());
platformUnique.setInfo(loginInfo.getInfo());
saveOrUpdate(platformUnique);
String oldUserId = platformUnique.getUserId();
TokenBean tokenBean = tieshengWebConfigurer.login(platformUnique);
if (tokenBean != null) {
// 添加登录日志
coreLogService.addLoginLog(platformUnique, tokenBean);
// 更新唯一值
if (!StrUtil.isEmpty(tokenBean.getId()) &&
!Objects.equals(oldUserId, tokenBean.getId())) {
platformUnique.setUserId(tokenBean.getId());
saveOrUpdate(platformUnique);
}
}
return tokenBean;
}
@Override
public void onLoginRedirect(TokenBean bean, String to, String extra, HttpServletResponse response) {
tieshengWebConfigurer.redirect(bean, to, extra, response);
}
@Override
public void onSignError(HttpServletResponse response) {
tieshengWebConfigurer.onSignError(response);
}
}

View File

@@ -1,33 +1,19 @@
package com.tiesheng.web.service; package com.tiesheng.web.service;
import cn.hutool.log.LogFactory; import cn.hutool.log.LogFactory;
import com.tiesheng.web.pojos.RequestUserInfo; import com.tiesheng.login.service.TsLoginConfigurer;
import com.tiesheng.web.pojos.dao.CoreConfigSystem;
import com.tiesheng.web.pojos.dao.CorePlatformUnique;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.ServletKit;
import com.tiesheng.util.exception.ApiRespEnum; import com.tiesheng.util.exception.ApiRespEnum;
import com.tiesheng.util.pojos.ApiResp; import com.tiesheng.util.pojos.ApiResp;
import com.tiesheng.web.pojos.dao.CoreConfigSystem;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
/** /**
* WEB配置 * 核心配置
* *
* @author hao * @author hao
*/ */
public interface TieshengWebConfigurer { public interface TieshengWebConfigurer {
/**
* 获取当前用户的姓名
*
* @return
*/
RequestUserInfo getCurrentUserName(TokenBean userId);
/** /**
* 添加其他异常处理 * 添加其他异常处理
* *
@@ -75,28 +61,16 @@ public interface TieshengWebConfigurer {
default void configSystemCheck(CoreConfigSystem configSystem) { default void configSystemCheck(CoreConfigSystem configSystem) {
} }
///////////////////////////////////////////////////////////////////////////
// 登录配置
///////////////////////////////////////////////////////////////////////////
/** /**
* 登录逻辑 * 登录配置
* *
* @param platformUnique
* @return * @return
*/ */
TokenBean login(CorePlatformUnique platformUnique); TsLoginConfigurer configureLogin();
/**
* 登录重定向
*
* @param bean
* @param extra
* @param response
*/
void redirect(TokenBean bean, String to, String extra, HttpServletResponse response);
/**
* 签名错误的时候
*/
default void onSignError(HttpServletResponse response) {
ServletKit.write(response, "404", "text");
}
} }

View File

@@ -2,25 +2,7 @@ SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; SET FOREIGN_KEY_CHECKS = 0;
-- ---------------------------- -- ----------------------------
-- Table structure for core_log_login -- Table structure for core_log_api
-- ----------------------------
CREATE TABLE `core_log_login`
(
`id` varchar(50) NOT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
`is_deleted` int(6) NOT NULL DEFAULT '0',
`user_id` varchar(50) DEFAULT NULL COMMENT '用户id',
`user_name` varchar(255) DEFAULT NULL COMMENT '用户姓名',
`platform` varchar(50) DEFAULT NULL COMMENT '登录方式',
`ip` varchar(100) DEFAULT NULL COMMENT 'ip',
`address` varchar(255) DEFAULT NULL COMMENT 'ip地址',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='日志-登录';
-- ----------------------------
-- Table structure for core_log_message
-- ---------------------------- -- ----------------------------
CREATE TABLE `core_log_api` CREATE TABLE `core_log_api`
( (