package com.terra.system.service.sys; import com.terra.common.entity.all.RedisCacheKey; import com.terra.common.entity.all.SettingData; import com.terra.system.entity.sys.LoginEntity; import com.terra.system.entity.sys.TokenEntity; import com.terra.system.entity.sys.UserEntity; import com.terra.common.helper.StringHelper; import com.terra.common.helper.WebHelper; import com.terra.system.mapper.sys.TokenMapper; import com.terra.system.mapper.sys.UserMapper; import com.terra.common.service.RedisService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; /** * 令牌表 * @author sws * @date 2022-09-28 */ @Service public class TokenService implements TokenMapper { @Resource TokenMapper tokenMapper; @Resource UserMapper userMapper; @Resource LoginService loginService; @Resource RedisService redisService; @Override public Integer selectCount(String name, Integer type) { name = StringHelper.getLikeUpperStr(name); return tokenMapper.selectCount(name, type); } @Override public List selectByPage(String name, Integer type, Integer limit, Integer offset) { name = StringHelper.getLikeUpperStr(name); return tokenMapper.selectByPage(name, type, limit, offset); } @Override public TokenEntity selectToken(int id) { return tokenMapper.selectToken(id); } @Override public List selectByIds(List ids) { return tokenMapper.selectByIds(ids); } @Override public TokenEntity selectOneById(Integer id) { return tokenMapper.selectOneById(id); } @Override public TokenEntity selectOneByToken(String token) { return tokenMapper.selectOneByToken(token); } @Override public List selectTokenAll() { return tokenMapper.selectTokenAll(); } @Override public Integer insertToken(TokenEntity tokenEntity) { return tokenMapper.insertToken(tokenEntity); } @Override public Integer insertTokens(List tokenEntity) { return tokenMapper.insertTokens(tokenEntity); } @Override public Integer deleteToken(int id) { TokenEntity entity = tokenMapper.selectToken(id); if (null == entity) { return 0; } clearCache(entity.getToken()); return tokenMapper.deleteToken(id); } @Override public Integer deleteTokens(List ids) { List list = tokenMapper.selectByIds(ids); if (null == list || list.isEmpty()) { return 0; } for (TokenEntity entity : list) { clearCache(entity.getToken()); } return tokenMapper.deleteTokens(ids); } @Override public Integer updateToken(TokenEntity tokenEntity) { return tokenMapper.updateToken(tokenEntity); } @Override public Integer updateTokenExpire(TokenEntity tokenEntity) { clearCache(tokenEntity.getToken()); return tokenMapper.updateTokenExpire(tokenEntity); } /** * 获取新的令牌实体类 */ public TokenEntity getNewToken(UserEntity ue, HttpServletRequest req) { return getNewToken(0, SettingData.TOKEN_EXPIRE, ue, req); } /** * 获取新的令牌实体类 */ public TokenEntity getNewToken(Integer type, Integer min, UserEntity ue, HttpServletRequest req) { TokenEntity te = new TokenEntity(); te.setToken(WebHelper.getGuid()); te.setDuration(min); te.setExpire(WebHelper.getTimestamp(min)); te.setType(type); te.setIp(WebHelper.getIpAddress(req)); te.setCreateUser(ue.getId()); te.setUname(ue.getUname()); return te; } /** * 是/否登录 */ public Boolean isLogin(HttpServletRequest req, HttpServletResponse res) { String token = WebHelper.getToken(req); if (StringHelper.isNull(token)) { return false; } TokenEntity te = getEntityByToken(token); return null != te; } /** * 登出 */ public Boolean logout(String token, HttpServletRequest req, HttpServletResponse res) { TokenEntity te = getEntityByToken(token); if (null == te) { return false; } // 清除Cookie WebHelper.deleteCookies(req, res); // 获取当前用户 UserEntity ue = getCurrentUser(req); if (ue == null) { return false; } // db,设置令牌过期 te.setUpdateUser(ue.getId()); Integer rows = updateTokenExpire(te); if (0 == rows) { return false; } // 写日志 LoginEntity le = loginService.getNewLogin(ue.getId(), 1, 3, 1, req); rows = loginService.insertLogin(le); return rows > 0; } /** * 清除缓存 */ public void clearCache(String token) { String tokenKey = RedisCacheKey.signTokenKey(token); redisService.delete(tokenKey); String userKey = RedisCacheKey.signUserKey(token); redisService.delete(userKey); } /** * 根据令牌获取实体 */ public TokenEntity getEntityByToken(String token) { String tokenKey = RedisCacheKey.signTokenKey(token); // redis Object obj = redisService.get(tokenKey); if (obj instanceof TokenEntity) { return (TokenEntity) obj; } // db TokenEntity te = selectOneByToken(token); if (null != te) { long min = StringHelper.getMinuteDifference(te.getExpire()); if (min > 0) { redisService.put(tokenKey, te, min, TimeUnit.MINUTES); } } return te; } /** * 保存token */ public void saveToken(UserEntity ue, TokenEntity te, HttpServletRequest req, HttpServletResponse res) { // 保存至Cookie WebHelper.saveToken2Cookie(te.getToken(), req, res); // 令牌保存至Redis String tokenKey = RedisCacheKey.signTokenKey(te.getToken()); redisService.put(tokenKey, te, te.getDuration(), TimeUnit.MINUTES); String userKey = RedisCacheKey.signUserKey(te.getToken()); ue.setBak(StringHelper.YMDHMS_FORMAT.format(new Date())); redisService.put(userKey, ue, te.getDuration(), TimeUnit.MINUTES); } /** * 获取当前用户 */ public UserEntity getCurrentUser(HttpServletRequest req) { String token = WebHelper.getToken(req); return getUserByToken(token); } /** * 根据令牌获取用户 */ public UserEntity getUserByToken(String token) { if (StringHelper.isNull(token)) { return null; } // redis String userKey = RedisCacheKey.signUserKey(token); Object obj = redisService.get(userKey); if (obj instanceof UserEntity) { return (UserEntity) obj; } // db UserEntity ue = userMapper.selectByToken(token); if (null != ue) { getEntityByToken(token); } return ue; } /** * 设置密码错误缓存 */ public void setPwdErrCache(UserEntity ue) { String key = RedisCacheKey.signPwdError(ue.getUid()); Object objCount = redisService.get(key); int count = objCount == null ? 1 : (int) objCount + 1; redisService.put(key, count, SettingData.PWD_ERR_TIME, TimeUnit.MINUTES); // 记录日志 HttpServletRequest req = WebHelper.getRequest(); LoginEntity le = loginService.getNewLogin(ue.getId(), 1, 1, 0, req); le.setDescr("密码不正确"); loginService.insertLogin(le); if (count >= SettingData.PWD_ERR_COUNT) { String token = WebHelper.getToken(req); HttpServletResponse res = WebHelper.getResponse(); logout(token, req, res); } } /** * 用户ID是/否禁用 */ public boolean isUidDisable(UserEntity ue) { String key = RedisCacheKey.signPwdError(ue.getUid()); Object objCount = redisService.get(key); return null != objCount && (int) objCount >= SettingData.PWD_ERR_COUNT; } }