This commit is contained in:
sxu 2025-02-02 20:08:03 +08:00
parent bd52203d90
commit 0a9a36b839
7 changed files with 513 additions and 306 deletions

View File

@ -1,74 +1,33 @@
package net.xnzn.api; //package net.xnzn.api;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.redis.service.RedisService;
import net.xnzn.domain.SmsCodeVerifyDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class SmsCodeApi {
private static final Logger log = LoggerFactory.getLogger(SmsCodeApi.class);
@Autowired
private RedisService redisService;
// public void sendSmsCodePost(String telephoneNumber) {
// this.sendSmsCodePost(telephoneNumber, "code_");
// }
// //
// public void sendSmsCodePost(String telephoneNumber, String cacheKey) { //import cn.hutool.core.util.ObjectUtil;
// String limitKey = "limit_" + telephoneNumber; //import com.alibaba.fastjson2.JSON;
// LocalDateTime now = LocalDateTime.now(); //import com.bonus.common.core.exception.ServiceException;
// LocalDateTime endOfDay = now.with(LocalTime.MAX); //import com.bonus.common.redis.service.RedisService;
// long expirTime = Math.max(1L, Duration.between(now, endOfDay).getSeconds()); //import net.xnzn.domain.SmsCodeVerifyDTO;
// String lastSendTimeKey = "last_send_time_" + telephoneNumber; //import org.slf4j.Logger;
// String lastSendTime = redisService.getCacheObject(lastSendTimeKey); //import org.slf4j.LoggerFactory;
// if (lastSendTime != null) { //import org.springframework.beans.factory.annotation.Autowired;
// long lastSendTimestamp = Long.parseLong(lastSendTime); //import org.springframework.stereotype.Service;
// long currentTimestamp = System.currentTimeMillis();
// long timeElapsed = currentTimestamp - lastSendTimestamp;
// if (timeElapsed < 60000L) {
// throw new ServiceException("notice_verify_repeat_sms_code_exception");
// }
// }
// //
// Integer times = RedisUtil.incr(limitKey, expirTime); //import java.time.Duration;
// if (times > 5) { //import java.time.LocalDateTime;
// throw new ServiceException("notice_verify_limit_sms_code_time"); //import java.time.LocalTime;
// } else { //import java.util.HashMap;
// int code = (int)((Math.random() * 9.0 + 1.0) * 100000.0); //import java.util.Map;
// String codeString = "" + code; //import java.util.concurrent.TimeUnit;
// Map<String, String> maps = new HashMap(); //
// maps.put("telephoneNumber", telephoneNumber); //@Service
// maps.put("sendCode", codeString); //public class SmsCodeApi {
// log.info("验证码发送code : {}", codeString); // private static final Logger log = LoggerFactory.getLogger(SmsCodeApi.class);
// //MqUtil.send(JSON.toJSONString(maps), LeMqConstant.Topic.NOTICE_VERIFICATION_CODE); //
// String key = cacheKey + telephoneNumber; // @Autowired
// redisService.setCacheObject(key, codeString, 300L, TimeUnit.SECONDS); // private RedisService redisService;
// redisService.setCacheObject(lastSendTimeKey, String.valueOf(System.currentTimeMillis())); //
// public boolean verifySmsCode(SmsCodeVerifyDTO smsCodeVerifyDTO, String cacheKey) {
// String key = cacheKey + smsCodeVerifyDTO.getTelephoneNumber();
// String code = redisService.getCacheObject(key); //RedisUtil.getString(key);
// log.info("redis缓存验证码code : {}", code);
// return ObjectUtil.isNotEmpty(code) && ObjectUtil.equal(code, smsCodeVerifyDTO.getCode());
// } // }
//} //}
// public boolean verifySmsCode(SmsCodeVerifyDTO smsCodeVerifyDTO) {
// return this.verifySmsCode(smsCodeVerifyDTO, "code_");
// }
public boolean verifySmsCode(SmsCodeVerifyDTO smsCodeVerifyDTO, String cacheKey) {
String key = cacheKey + smsCodeVerifyDTO.getTelephoneNumber();
String code = redisService.getCacheObject(key); //RedisUtil.getString(key);
log.info("redis缓存验证码code : {}", code);
return ObjectUtil.isNotEmpty(code) && ObjectUtil.equal(code, smsCodeVerifyDTO.getCode());
}
}

View File

@ -31,4 +31,8 @@ public class CustInfoAppIdLoginVO implements Serializable {
private Long loginTime; private Long loginTime;
@ApiModelProperty("过期时间") @ApiModelProperty("过期时间")
private Long expireTime; private Long expireTime;
@ApiModelProperty("")
private Long expireIn;
@ApiModelProperty("是否登录")
private boolean isLogin;
} }

View File

@ -1,217 +1,217 @@
package net.xnzn.service; //package net.xnzn.service;
//
import cn.hutool.core.util.ObjectUtil; //import cn.hutool.core.util.ObjectUtil;
import com.bonus.common.core.constant.SecurityConstants; //import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.utils.JwtUtils; //import com.bonus.common.core.utils.JwtUtils;
import com.bonus.common.core.utils.ServletUtils; //import com.bonus.common.core.utils.ServletUtils;
import com.bonus.common.core.utils.StringUtils; //import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.ip.IpUtils; //import com.bonus.common.core.utils.ip.IpUtils;
import com.bonus.common.core.utils.uuid.IdUtils; //import com.bonus.common.core.utils.uuid.IdUtils;
import com.bonus.common.core.web.domain.AjaxResult; //import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.redis.service.RedisService; //import com.bonus.common.redis.service.RedisService;
import com.bonus.common.security.utils.SecurityUtils; //import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.config.SystemConfig; //import com.bonus.config.SystemConfig;
import com.bonus.system.api.RemoteUserService; //import com.bonus.system.api.RemoteUserService;
import com.bonus.system.api.domain.SysUser; //import com.bonus.system.api.domain.SysUser;
import com.bonus.system.api.model.LoginUser; //import com.bonus.system.api.model.LoginUser;
import net.xnzn.domain.CustInfoAppIdLoginVO; //import net.xnzn.domain.CustInfoAppIdLoginVO;
import org.slf4j.Logger; //import org.slf4j.Logger;
import org.slf4j.LoggerFactory; //import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import javax.annotation.Resource; //import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletRequest;
import java.util.Date; //import java.util.Date;
import java.util.HashMap; //import java.util.HashMap;
import java.util.Map; //import java.util.Map;
import java.util.concurrent.TimeUnit; //import java.util.concurrent.TimeUnit;
//
/** ///**
* token验证处理 // * token验证处理
* // *
* @author bonus // * @author bonus
*/ // */
@Component //@Component
public class TokenService { //public class TokenService {
//
@Resource // @Resource
private SystemConfig systemConfig; // private SystemConfig systemConfig;
//
private static final Logger log = LoggerFactory.getLogger(TokenService.class); // private static final Logger log = LoggerFactory.getLogger(TokenService.class);
//
@Autowired // @Autowired
private RedisService redisService; // private RedisService redisService;
//
@Resource // @Resource
RemoteUserService remoteUserService; // RemoteUserService remoteUserService;
//
protected static final long MILLIS_SECOND = 1000; // protected static final long MILLIS_SECOND = 1000;
//
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; // protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
//
private final static long EXPIRETIME = 720L; // private final static long EXPIRETIME = 720L;
//
private final static String CUST_ACCESS_TOKEN = "cust_login_tokens:"; // private final static String CUST_ACCESS_TOKEN = "cust_login_tokens:";
//
private final static String CUST_LOGIN_USER_KEY = "cust_login_users:"; // private final static String CUST_LOGIN_USER_KEY = "cust_login_users:";
//
private final static Long MILLIS_MINUTE_TEN = 120L * MILLIS_MINUTE; // private final static Long MILLIS_MINUTE_TEN = 120L * MILLIS_MINUTE;
//
private static final String DETAILS_USER_ID = "user_id"; // private static final String DETAILS_USER_ID = "user_id";
private static final String DETAILS_USERNAME = "username"; // private static final String DETAILS_USERNAME = "username";
private static final String USER_KEY = "user_key"; // private static final String USER_KEY = "user_key";
private static final String LOGIN_USER = "login_user"; // private static final String LOGIN_USER = "login_user";
//
/** // /**
* 创建令牌 // * 创建令牌
*/ // */
public Map<String, Object> createToken(CustInfoAppIdLoginVO loginUser) { // public Map<String, Object> createToken(CustInfoAppIdLoginVO loginUser) {
// 检查并删除已有的token // // 检查并删除已有的token
delExistingToken(loginUser.getCustId()); // delExistingToken(loginUser.getCustId());
String token = IdUtils.fastUUID(); // String token = IdUtils.fastUUID();
Long custId = loginUser.getCustId(); // Long custId = loginUser.getCustId();
String userName = loginUser.getCustName(); // String userName = loginUser.getCustName();
loginUser.setToken(token); // loginUser.setToken(token);
loginUser.setCustId(custId); // loginUser.setCustId(custId);
loginUser.setCustName(userName); // loginUser.setCustName(userName);
loginUser.setIpaddr(IpUtils.getIpAddr()); // loginUser.setIpaddr(IpUtils.getIpAddr());
refreshToken(loginUser); // refreshToken(loginUser);
// Jwt存储信息 // // Jwt存储信息
Map<String, Object> claimsMap = new HashMap<String, Object>(16); // Map<String, Object> claimsMap = new HashMap<String, Object>(16);
claimsMap.put(USER_KEY, token); // claimsMap.put(USER_KEY, token);
claimsMap.put(DETAILS_USER_ID, custId); // claimsMap.put(DETAILS_USER_ID, custId);
claimsMap.put(DETAILS_USERNAME, userName); // claimsMap.put(DETAILS_USERNAME, userName);
String accessToken = JwtUtils.createToken(claimsMap); // String accessToken = JwtUtils.createToken(claimsMap);
Map<String, Object> rspMap = new HashMap<String, Object>(16); // Map<String, Object> rspMap = new HashMap<String, Object>(16);
rspMap.put("cust_access_token", accessToken); // rspMap.put("cust_access_token", accessToken);
rspMap.put("cust_expires_in", EXPIRETIME); // rspMap.put("expires_in", EXPIRETIME);
rspMap.put("cust_isLogin", isLogin(String.valueOf(custId))); // rspMap.put("isLogin", isLogin(String.valueOf(custId)));
long tokenTime = getTokenTime(); // long tokenTime = getTokenTime();
//对token进行存储 // //对token进行存储
redisService.setCacheObject(CUST_LOGIN_USER_KEY + custId, token, tokenTime, TimeUnit.MINUTES); // redisService.setCacheObject(CUST_LOGIN_USER_KEY + custId, token, tokenTime, TimeUnit.MINUTES);
return rspMap; // return rspMap;
} // }
//
public boolean isLogin(String userId) { // public boolean isLogin(String userId) {
String existingTokenKey = redisService.getCacheObject(CUST_LOGIN_USER_KEY + userId); // String existingTokenKey = redisService.getCacheObject(CUST_LOGIN_USER_KEY + userId);
return existingTokenKey != null; // return existingTokenKey != null;
} // }
//
public boolean isKey(String key) { // public boolean isKey(String key) {
return redisService.hasKey(getTokenKey(key)); // return redisService.hasKey(getTokenKey(key));
} // }
//
/** // /**
* 删除已有的token // * 删除已有的token
*/ // */
public void delExistingToken(Long userId) { // public void delExistingToken(Long userId) {
String existingTokenKey = redisService.getCacheObject(CUST_LOGIN_USER_KEY + userId); // String existingTokenKey = redisService.getCacheObject(CUST_LOGIN_USER_KEY + userId);
if (existingTokenKey != null) { // if (existingTokenKey != null) {
redisService.deleteObject(getTokenKey(existingTokenKey)); // redisService.deleteObject(getTokenKey(existingTokenKey));
redisService.deleteObject(CUST_LOGIN_USER_KEY + userId); // redisService.deleteObject(CUST_LOGIN_USER_KEY + userId);
} // }
} // }
//
/** // /**
* 获取用户身份信息 // * 获取用户身份信息
* // *
* @return 用户信息 // * @return 用户信息
*/ // */
public CustInfoAppIdLoginVO getLoginUser() { // public CustInfoAppIdLoginVO getLoginUser() {
return getLoginUser(ServletUtils.getRequest()); // return getLoginUser(ServletUtils.getRequest());
} // }
//
/** // /**
* 获取用户身份信息 // * 获取用户身份信息
* // *
* @return 用户信息 // * @return 用户信息
*/ // */
public CustInfoAppIdLoginVO getLoginUser(HttpServletRequest request) { // public CustInfoAppIdLoginVO getLoginUser(HttpServletRequest request) {
// 获取请求携带的令牌 // // 获取请求携带的令牌
String token = SecurityUtils.getToken(request); // String token = SecurityUtils.getToken(request);
return getLoginUser(token); // return getLoginUser(token);
} // }
//
/** // /**
* 获取用户身份信息 // * 获取用户身份信息
* // *
* @return 用户信息 // * @return 用户信息
*/ // */
public CustInfoAppIdLoginVO getLoginUser(String token) { // public CustInfoAppIdLoginVO getLoginUser(String token) {
CustInfoAppIdLoginVO user = null; // CustInfoAppIdLoginVO user = null;
try { // try {
if (StringUtils.isNotEmpty(token)) { // if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token); // String userkey = JwtUtils.getUserKey(token);
user = redisService.getCacheObject(getTokenKey(userkey)); // user = redisService.getCacheObject(getTokenKey(userkey));
return user; // return user;
} // }
} catch (Exception e) { // } catch (Exception e) {
log.error("获取用户信息异常'{}'", e.getMessage()); // log.error("获取用户信息异常'{}'", e.getMessage());
} // }
return user; // return user;
} // }
//
/** // /**
* 设置用户身份信息 // * 设置用户身份信息
*/ // */
public void setLoginUser(CustInfoAppIdLoginVO loginUser) { // public void setLoginUser(CustInfoAppIdLoginVO loginUser) {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) { // if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
refreshToken(loginUser); // refreshToken(loginUser);
} // }
} // }
//
/** // /**
* 删除用户缓存信息 // * 删除用户缓存信息
*/ // */
public void delLoginUser(String token) { // public void delLoginUser(String token) {
if (StringUtils.isNotEmpty(token)) { // if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token); // String userkey = JwtUtils.getUserKey(token);
redisService.deleteObject(getTokenKey(userkey)); // redisService.deleteObject(getTokenKey(userkey));
} // }
} // }
//
/** // /**
* 验证令牌有效期相差不足120分钟自动刷新缓存 // * 验证令牌有效期相差不足120分钟自动刷新缓存
* // *
* @param loginUser // * @param loginUser
*/ // */
public void verifyToken(CustInfoAppIdLoginVO loginUser) { // public void verifyToken(CustInfoAppIdLoginVO loginUser) {
long expireTime = loginUser.getExpireTime(); // long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis(); // long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { // if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshToken(loginUser); // refreshToken(loginUser);
} // }
} // }
//
/** // /**
* 刷新令牌有效期 // * 刷新令牌有效期
* // *
* @param loginUser 登录信息 // * @param loginUser 登录信息
*/ // */
public void refreshToken(CustInfoAppIdLoginVO loginUser) { // public void refreshToken(CustInfoAppIdLoginVO loginUser) {
long tokenTime = getTokenTime(); // long tokenTime = getTokenTime();
loginUser.setLoginTime(System.currentTimeMillis()); // loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + tokenTime * MILLIS_MINUTE); // loginUser.setExpireTime(loginUser.getLoginTime() + tokenTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存 // // 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken()); // String userKey = getTokenKey(loginUser.getToken());
redisService.setCacheObject(userKey, loginUser, tokenTime, TimeUnit.MINUTES); // redisService.setCacheObject(userKey, loginUser, tokenTime, TimeUnit.MINUTES);
} // }
//
private String getTokenKey(String token) { // private String getTokenKey(String token) {
return CUST_ACCESS_TOKEN + token; // return CUST_ACCESS_TOKEN + token;
} // }
//
private Long getTokenTime(){ // private Long getTokenTime(){
long tokenTime = 20L; // long tokenTime = 20L;
String redisResult = redisService.getCacheObject("sys_config:"+ "sys.visit.tokentime"); // String redisResult = redisService.getCacheObject("sys_config:"+ "sys.visit.tokentime");
if(!redisResult.isEmpty()) { // if(!redisResult.isEmpty()) {
tokenTime = Long.parseLong(redisResult); // tokenTime = Long.parseLong(redisResult);
}else { // }else {
Long result = systemConfig.getTokenTime(); // Long result = systemConfig.getTokenTime();
if (!ObjectUtil.isEmpty(result)){ // if (!ObjectUtil.isEmpty(result)){
tokenTime = result; // tokenTime = result;
} // }
} // }
return tokenTime; // return tokenTime;
} // }
} //}

View File

@ -0,0 +1,24 @@
package com.bonus.auth.api;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.common.redis.service.RedisService;
import net.xnzn.domain.SmsCodeVerifyDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SmsCodeApi {
private static final Logger log = LoggerFactory.getLogger(SmsCodeApi.class);
@Autowired
private RedisService redisService;
public boolean verifySmsCode(SmsCodeVerifyDTO smsCodeVerifyDTO, String cacheKey) {
String key = cacheKey + smsCodeVerifyDTO.getTelephoneNumber();
String code = redisService.getCacheObject(key); //RedisUtil.getString(key);
log.info("redis缓存验证码code : {}", code);
return ObjectUtil.isNotEmpty(code) && ObjectUtil.equal(code, smsCodeVerifyDTO.getCode());
}
}

View File

@ -3,7 +3,7 @@ package com.bonus.auth.controller;
import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.bonus.common.core.constant.CacheConstants; import com.bonus.common.core.constant.CacheConstants;
import net.xnzn.api.SmsCodeApi; import com.bonus.auth.api.SmsCodeApi;
import net.xnzn.constant.CustLoginTypeEnum; import net.xnzn.constant.CustLoginTypeEnum;
import net.xnzn.constant.DelFlagEnum; import net.xnzn.constant.DelFlagEnum;
import net.xnzn.constant.LeConstants; import net.xnzn.constant.LeConstants;
@ -29,7 +29,6 @@ import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.config.SystemConfig; import com.bonus.config.SystemConfig;
import com.bonus.system.api.RemoteConfigService; import com.bonus.system.api.RemoteConfigService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.xnzn.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -37,7 +36,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.*; import java.util.*;
@ -49,13 +47,11 @@ import java.util.*;
@RestController @RestController
@Slf4j @Slf4j
public class TokenController { public class TokenController {
@Resource @Resource
private SystemConfig config; private SystemConfig config;
@Autowired @Autowired
@Lazy private CustTokenService tokenService;
private TokenService tokenService;
@Autowired @Autowired
private SysLoginService sysLoginService; private SysLoginService sysLoginService;
@ -70,7 +66,6 @@ public class TokenController {
private RemoteConfigService configService; private RemoteConfigService configService;
@Autowired @Autowired
@Lazy
private SmsCodeApi smsCodeApi; private SmsCodeApi smsCodeApi;
@Autowired @Autowired
@ -80,7 +75,7 @@ public class TokenController {
private CustCasualMapper custCasualMapper; private CustCasualMapper custCasualMapper;
private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
private static final String CUST_LOGIN_TOKEN_KEY = "cust_login_tokens:"; //private static final String CUST_LOGIN_TOKEN_KEY = "cust_login_tokens:";
// @PostMapping("isLogin") // @PostMapping("isLogin")
// public R<?> isLogin(@RequestBody LoginBody form) { // public R<?> isLogin(@RequestBody LoginBody form) {
@ -104,12 +99,15 @@ public class TokenController {
{ {
concurrency = Long.parseLong(result.get("msg").toString()); concurrency = Long.parseLong(result.get("msg").toString());
} }
Collection<String> keys = redisService.keys(CUST_LOGIN_TOKEN_KEY + "*"); Collection<String> keys = redisService.keys(CustTokenService.CUST_LOGIN_TOKEN + "*");
if (keys.size() >= concurrency){ if (keys.size() >= concurrency){
return R.fail("当前系统用户并发数超过系统配置,请稍后再试"); return R.fail("当前系统用户并发数超过系统配置,请稍后再试");
} }
CustInfoAppIdLoginVO loginUser = custLogin(form); CustInfoAppIdLoginVO loginUser = custLogin(form);
//return R.ok(tokenService.createToken(loginUser)); Map<String, Object> map = tokenService.createToken(loginUser);
loginUser.setToken((String) map.get(CustTokenService.ACCESS_TOKEN));
loginUser.setExpireIn((Long) map.get(CustTokenService.EXPIRES_IN));
loginUser.setLogin((boolean) map.get(CustTokenService.IS_LOGIN));
return R.ok(loginUser); return R.ok(loginUser);
} }

View File

@ -0,0 +1,219 @@
package com.bonus.auth.service;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.common.core.utils.JwtUtils;
import com.bonus.common.core.utils.ServletUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.ip.IpUtils;
import com.bonus.common.core.utils.uuid.IdUtils;
import com.bonus.common.redis.service.RedisService;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.config.SystemConfig;
import com.bonus.system.api.RemoteUserService;
import net.xnzn.domain.CustInfoAppIdLoginVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* token验证处理
*
* @author bonus
*/
@Component
public class CustTokenService {
@Resource
private SystemConfig systemConfig;
private static final Logger log = LoggerFactory.getLogger(CustTokenService.class);
@Autowired
private RedisService redisService;
@Resource
RemoteUserService remoteUserService;
protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private final static long EXPIRETIME = 720L;
public final static String ACCESS_TOKEN = "access_tokens:";
public final static String EXPIRES_IN = "expires_in";
public final static String IS_LOGIN = "isLogin";
public final static String CUST_LOGIN_TOKEN = "cust_login_tokens:";
private final static String CUST_LOGIN_USER_KEY = "cust_login_users:";
private final static Long MILLIS_MINUTE_TEN = 120L * MILLIS_MINUTE;
private static final String DETAILS_USER_ID = "user_id";
private static final String DETAILS_USERNAME = "username";
private static final String USER_KEY = "user_key";
private static final String LOGIN_USER = "login_user";
/**
* 创建令牌
*/
public Map<String, Object> createToken(CustInfoAppIdLoginVO loginUser) {
// 检查并删除已有的token
delExistingToken(loginUser.getCustId());
String token = IdUtils.fastUUID();
Long custId = loginUser.getCustId();
String userName = loginUser.getCustName();
loginUser.setToken(token);
loginUser.setCustId(custId);
loginUser.setCustName(userName);
loginUser.setIpaddr(IpUtils.getIpAddr());
refreshToken(loginUser);
// Jwt存储信息
Map<String, Object> claimsMap = new HashMap<String, Object>(16);
claimsMap.put(USER_KEY, token);
claimsMap.put(DETAILS_USER_ID, custId);
claimsMap.put(DETAILS_USERNAME, userName);
String accessToken = JwtUtils.createToken(claimsMap);
Map<String, Object> rspMap = new HashMap<String, Object>(16);
rspMap.put(ACCESS_TOKEN, accessToken);
rspMap.put(EXPIRES_IN, EXPIRETIME);
rspMap.put(IS_LOGIN, isLogin(String.valueOf(custId)));
long tokenTime = getTokenTime();
//对token进行存储
redisService.setCacheObject(CUST_LOGIN_USER_KEY + custId, token, tokenTime, TimeUnit.MINUTES);
return rspMap;
}
public boolean isLogin(String userId) {
String existingTokenKey = redisService.getCacheObject(CUST_LOGIN_USER_KEY + userId);
return existingTokenKey != null;
}
public boolean isKey(String key) {
return redisService.hasKey(getTokenKey(key));
}
/**
* 删除已有的token
*/
public void delExistingToken(Long userId) {
String existingTokenKey = redisService.getCacheObject(CUST_LOGIN_USER_KEY + userId);
if (existingTokenKey != null) {
redisService.deleteObject(getTokenKey(existingTokenKey));
redisService.deleteObject(CUST_LOGIN_USER_KEY + userId);
}
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public CustInfoAppIdLoginVO getLoginUser() {
return getLoginUser(ServletUtils.getRequest());
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public CustInfoAppIdLoginVO getLoginUser(HttpServletRequest request) {
// 获取请求携带的令牌
String token = SecurityUtils.getToken(request);
return getLoginUser(token);
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public CustInfoAppIdLoginVO getLoginUser(String token) {
CustInfoAppIdLoginVO user = null;
try {
if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token);
user = redisService.getCacheObject(getTokenKey(userkey));
return user;
}
} catch (Exception e) {
log.error("获取用户信息异常'{}'", e.getMessage());
}
return user;
}
/**
* 设置用户身份信息
*/
public void setLoginUser(CustInfoAppIdLoginVO loginUser) {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
refreshToken(loginUser);
}
}
/**
* 删除用户缓存信息
*/
public void delLoginUser(String token) {
if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token);
redisService.deleteObject(getTokenKey(userkey));
}
}
/**
* 验证令牌有效期相差不足120分钟自动刷新缓存
*
* @param loginUser
*/
public void verifyToken(CustInfoAppIdLoginVO loginUser) {
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshToken(loginUser);
}
}
/**
* 刷新令牌有效期
*
* @param loginUser 登录信息
*/
public void refreshToken(CustInfoAppIdLoginVO loginUser) {
long tokenTime = getTokenTime();
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + tokenTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisService.setCacheObject(userKey, loginUser, tokenTime, TimeUnit.MINUTES);
}
private String getTokenKey(String token) {
return CUST_LOGIN_TOKEN + token;
}
private Long getTokenTime(){
long tokenTime = 20L;
String redisResult = redisService.getCacheObject("sys_config:"+ "sys.visit.tokentime");
if(!redisResult.isEmpty()) {
tokenTime = Long.parseLong(redisResult);
}else {
Long result = systemConfig.getTokenTime();
if (!ObjectUtil.isEmpty(result)){
tokenTime = result;
}
}
return tokenTime;
}
}

View File

@ -3,7 +3,7 @@ package net.xnzn.core.customer.service.impl;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.bonus.common.core.constant.CacheConstants; import com.bonus.common.core.constant.CacheConstants;
import com.bonus.common.core.exception.ServiceException; import com.bonus.common.core.exception.ServiceException;
import net.xnzn.api.SmsCodeApi; import com.bonus.common.redis.service.RedisService;
import net.xnzn.constant.RetCodeEnum; import net.xnzn.constant.RetCodeEnum;
import net.xnzn.core.customer.api.CustCasualApi; import net.xnzn.core.customer.api.CustCasualApi;
import net.xnzn.core.customer.dto.CustChangePasswordDTO; import net.xnzn.core.customer.dto.CustChangePasswordDTO;
@ -25,12 +25,8 @@ import java.util.*;
@Service @Service
public class CustInfoServiceImpl implements CustInfoService { public class CustInfoServiceImpl implements CustInfoService {
private static final Logger log = LoggerFactory.getLogger(CustInfoServiceImpl.class); private static final Logger log = LoggerFactory.getLogger(CustInfoServiceImpl.class);
// @Autowired
// @Lazy
// private AesEncryptUtil aesEncryptUtil;
@Autowired @Autowired
@Lazy private RedisService redisService;
private SmsCodeApi smsCodeApi;
@Autowired @Autowired
@Lazy @Lazy
private CustCasualApi custCasualApi; private CustCasualApi custCasualApi;
@ -74,7 +70,7 @@ public class CustInfoServiceImpl implements CustInfoService {
SmsCodeVerifyDTO smsCodeVerifyDTO = new SmsCodeVerifyDTO(); SmsCodeVerifyDTO smsCodeVerifyDTO = new SmsCodeVerifyDTO();
smsCodeVerifyDTO.setTelephoneNumber(content.getMobile()); smsCodeVerifyDTO.setTelephoneNumber(content.getMobile());
smsCodeVerifyDTO.setCode(content.getCode()); smsCodeVerifyDTO.setCode(content.getCode());
if (!this.smsCodeApi.verifySmsCode(smsCodeVerifyDTO, CacheConstants.VERIFICATION_CODE)) { if (!verifySmsCode(smsCodeVerifyDTO, CacheConstants.VERIFICATION_CODE)) {
throw new ServiceException("验证码异常"); throw new ServiceException("验证码异常");
} else { } else {
CustInfo custInfoQuery = new CustInfo(); CustInfo custInfoQuery = new CustInfo();
@ -93,4 +89,11 @@ public class CustInfoServiceImpl implements CustInfoService {
} }
} }
public boolean verifySmsCode(SmsCodeVerifyDTO smsCodeVerifyDTO, String cacheKey) {
String key = cacheKey + smsCodeVerifyDTO.getTelephoneNumber();
String code = redisService.getCacheObject(key); //RedisUtil.getString(key);
log.info("redis缓存验证码code : {}", code);
return ObjectUtil.isNotEmpty(code) && ObjectUtil.equal(code, smsCodeVerifyDTO.getCode());
}
} }