mirror of https://github.com/elunez/eladmin
parent
f0ed88c51e
commit
cf3655adf4
|
@ -19,13 +19,11 @@ import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.data.redis.connection.RedisConnection;
|
import org.springframework.data.redis.connection.RedisConnection;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.*;
|
import org.springframework.data.redis.core.*;
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -36,9 +34,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
@SuppressWarnings({"unchecked", "all"})
|
@SuppressWarnings({"unchecked", "all"})
|
||||||
public class RedisUtils {
|
public class RedisUtils {
|
||||||
private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
|
private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
|
||||||
|
|
||||||
private RedisTemplate<Object, Object> redisTemplate;
|
private RedisTemplate<Object, Object> redisTemplate;
|
||||||
@Value("${jwt.online-key}")
|
|
||||||
private String onlineKey;
|
|
||||||
|
|
||||||
public RedisUtils(RedisTemplate<Object, Object> redisTemplate) {
|
public RedisUtils(RedisTemplate<Object, Object> redisTemplate) {
|
||||||
this.redisTemplate = redisTemplate;
|
this.redisTemplate = redisTemplate;
|
||||||
|
@ -197,6 +194,21 @@ public class RedisUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量模糊删除key
|
||||||
|
* @param pattern
|
||||||
|
*/
|
||||||
|
public void scanDel(String pattern){
|
||||||
|
ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
|
||||||
|
try (Cursor<byte[]> cursor = redisTemplate.executeWithStickyConnection(
|
||||||
|
(RedisCallback<Cursor<byte[]>>) connection -> (Cursor<byte[]>) new ConvertingCursor<>(
|
||||||
|
connection.scan(options), redisTemplate.getKeySerializer()::deserialize))) {
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
redisTemplate.delete(cursor.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============================String=============================
|
// ============================String=============================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class LoginProperties {
|
||||||
|
|
||||||
private LoginCode loginCode;
|
private LoginCode loginCode;
|
||||||
|
|
||||||
public static final String cacheKey = "USER-LOGIN-DATA";
|
public static final String cacheKey = "user-login-cache:";
|
||||||
|
|
||||||
public boolean isSingleLogin() {
|
public boolean isSingleLogin() {
|
||||||
return singleLogin;
|
return singleLogin;
|
||||||
|
|
|
@ -98,8 +98,6 @@ public class AuthorizationController {
|
||||||
// SecurityContextHolder.getContext().setAuthentication(authentication);
|
// SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
String token = tokenProvider.createToken(authentication);
|
String token = tokenProvider.createToken(authentication);
|
||||||
final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal();
|
final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal();
|
||||||
// 保存在线信息
|
|
||||||
onlineUserService.save(jwtUserDto, token, request);
|
|
||||||
// 返回 token 与 用户信息
|
// 返回 token 与 用户信息
|
||||||
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
|
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
|
||||||
put("token", properties.getTokenStartWith() + token);
|
put("token", properties.getTokenStartWith() + token);
|
||||||
|
@ -107,8 +105,11 @@ public class AuthorizationController {
|
||||||
}};
|
}};
|
||||||
if (loginProperties.isSingleLogin()) {
|
if (loginProperties.isSingleLogin()) {
|
||||||
// 踢掉之前已经登录的token
|
// 踢掉之前已经登录的token
|
||||||
onlineUserService.checkLoginOnUser(authUser.getUsername(), token);
|
onlineUserService.kickOutForUsername(authUser.getUsername());
|
||||||
}
|
}
|
||||||
|
// 保存在线信息
|
||||||
|
onlineUserService.save(jwtUserDto, token, request);
|
||||||
|
// 返回登录信息
|
||||||
return ResponseEntity.ok(authInfo);
|
return ResponseEntity.ok(authInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,25 +45,25 @@ public class OnlineController {
|
||||||
@ApiOperation("查询在线用户")
|
@ApiOperation("查询在线用户")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@PreAuthorize("@el.check()")
|
@PreAuthorize("@el.check()")
|
||||||
public ResponseEntity<PageResult<OnlineUserDto>> queryOnlineUser(String filter, Pageable pageable){
|
public ResponseEntity<PageResult<OnlineUserDto>> queryOnlineUser(String username, Pageable pageable){
|
||||||
return new ResponseEntity<>(onlineUserService.getAll(filter, pageable),HttpStatus.OK);
|
return new ResponseEntity<>(onlineUserService.getAll(username, pageable),HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("导出数据")
|
@ApiOperation("导出数据")
|
||||||
@GetMapping(value = "/download")
|
@GetMapping(value = "/download")
|
||||||
@PreAuthorize("@el.check()")
|
@PreAuthorize("@el.check()")
|
||||||
public void exportOnlineUser(HttpServletResponse response, String filter) throws IOException {
|
public void exportOnlineUser(HttpServletResponse response, String username) throws IOException {
|
||||||
onlineUserService.download(onlineUserService.getAll(filter), response);
|
onlineUserService.download(onlineUserService.getAll(username), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("踢出用户")
|
@ApiOperation("踢出用户")
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@PreAuthorize("@el.check()")
|
@PreAuthorize("@el.check()")
|
||||||
public ResponseEntity<Object> deleteOnlineUser(@RequestBody Set<String> keys) throws Exception {
|
public ResponseEntity<Object> deleteOnlineUser(@RequestBody Set<String> keys) throws Exception {
|
||||||
for (String key : keys) {
|
for (String token : keys) {
|
||||||
// 解密Key
|
// 解密Key
|
||||||
key = EncryptUtils.desDecrypt(key);
|
token = EncryptUtils.desDecrypt(token);
|
||||||
onlineUserService.kickOut(key);
|
onlineUserService.logout(token);
|
||||||
}
|
}
|
||||||
return new ResponseEntity<>(HttpStatus.OK);
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@ public class TokenFilter extends GenericFilterBean {
|
||||||
OnlineUserDto onlineUserDto = null;
|
OnlineUserDto onlineUserDto = null;
|
||||||
boolean cleanUserCache = false;
|
boolean cleanUserCache = false;
|
||||||
try {
|
try {
|
||||||
onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token);
|
String loginKey = tokenProvider.loginKey(token);
|
||||||
|
onlineUserDto = onlineUserService.getOne(loginKey);
|
||||||
} catch (ExpiredJwtException e) {
|
} catch (ExpiredJwtException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
cleanUserCache = true;
|
cleanUserCache = true;
|
||||||
|
|
|
@ -18,6 +18,7 @@ package me.zhengjie.modules.security.security;
|
||||||
import cn.hutool.core.date.DateField;
|
import cn.hutool.core.date.DateField;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
import io.jsonwebtoken.*;
|
import io.jsonwebtoken.*;
|
||||||
import io.jsonwebtoken.io.Decoders;
|
import io.jsonwebtoken.io.Decoders;
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
@ -120,4 +121,15 @@ public class TokenProvider implements InitializingBean {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录用户RedisKey
|
||||||
|
* @param token /
|
||||||
|
* @return key
|
||||||
|
*/
|
||||||
|
public String loginKey(String token) {
|
||||||
|
Claims claims = getClaims(token);
|
||||||
|
String md5Token = DigestUtil.md5Hex(token);
|
||||||
|
return properties.getOnlineKey() + claims.getSubject() + "-" + md5Token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package me.zhengjie.modules.security.service;
|
package me.zhengjie.modules.security.service;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.zhengjie.modules.security.security.TokenProvider;
|
||||||
import me.zhengjie.utils.PageResult;
|
import me.zhengjie.utils.PageResult;
|
||||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||||
|
@ -28,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Zheng Jie
|
* @author Zheng Jie
|
||||||
|
@ -35,16 +38,13 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
public class OnlineUserService {
|
public class OnlineUserService {
|
||||||
|
|
||||||
private final SecurityProperties properties;
|
private final SecurityProperties properties;
|
||||||
|
private final TokenProvider tokenProvider;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
|
|
||||||
public OnlineUserService(SecurityProperties properties, RedisUtils redisUtils) {
|
|
||||||
this.properties = properties;
|
|
||||||
this.redisUtils = redisUtils;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存在线用户信息
|
* 保存在线用户信息
|
||||||
* @param jwtUserDto /
|
* @param jwtUserDto /
|
||||||
|
@ -62,17 +62,18 @@ public class OnlineUserService {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(),e);
|
log.error(e.getMessage(),e);
|
||||||
}
|
}
|
||||||
redisUtils.set(properties.getOnlineKey() + token, onlineUserDto, properties.getTokenValidityInSeconds()/1000);
|
String loginKey = tokenProvider.loginKey(token);
|
||||||
|
redisUtils.set(loginKey, onlineUserDto, properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询全部数据
|
* 查询全部数据
|
||||||
* @param filter /
|
* @param username /
|
||||||
* @param pageable /
|
* @param pageable /
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public PageResult<OnlineUserDto> getAll(String filter, Pageable pageable){
|
public PageResult<OnlineUserDto> getAll(String username, Pageable pageable){
|
||||||
List<OnlineUserDto> onlineUserDtos = getAll(filter);
|
List<OnlineUserDto> onlineUserDtos = getAll(username);
|
||||||
return PageUtil.toPage(
|
return PageUtil.toPage(
|
||||||
PageUtil.paging(pageable.getPageNumber(),pageable.getPageSize(), onlineUserDtos),
|
PageUtil.paging(pageable.getPageNumber(),pageable.getPageSize(), onlineUserDtos),
|
||||||
onlineUserDtos.size()
|
onlineUserDtos.size()
|
||||||
|
@ -81,43 +82,29 @@ public class OnlineUserService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询全部数据,不分页
|
* 查询全部数据,不分页
|
||||||
* @param filter /
|
* @param username /
|
||||||
* @return /
|
* @return /
|
||||||
*/
|
*/
|
||||||
public List<OnlineUserDto> getAll(String filter){
|
public List<OnlineUserDto> getAll(String username){
|
||||||
List<String> keys = redisUtils.scan(properties.getOnlineKey() + "*");
|
String loginKey = properties.getOnlineKey() +
|
||||||
|
(StringUtils.isBlank(username) ? "" : "*" + username);
|
||||||
|
List<String> keys = redisUtils.scan(loginKey + "*");
|
||||||
Collections.reverse(keys);
|
Collections.reverse(keys);
|
||||||
List<OnlineUserDto> onlineUserDtos = new ArrayList<>();
|
List<OnlineUserDto> onlineUserDtos = new ArrayList<>();
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
OnlineUserDto onlineUserDto = (OnlineUserDto) redisUtils.get(key);
|
onlineUserDtos.add((OnlineUserDto) redisUtils.get(key));
|
||||||
if(StringUtils.isNotBlank(filter)){
|
|
||||||
if(onlineUserDto.toString().contains(filter)){
|
|
||||||
onlineUserDtos.add(onlineUserDto);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onlineUserDtos.add(onlineUserDto);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onlineUserDtos.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
|
onlineUserDtos.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
|
||||||
return onlineUserDtos;
|
return onlineUserDtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 踢出用户
|
|
||||||
* @param key /
|
|
||||||
*/
|
|
||||||
public void kickOut(String key){
|
|
||||||
key = properties.getOnlineKey() + key;
|
|
||||||
redisUtils.del(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退出登录
|
* 退出登录
|
||||||
* @param token /
|
* @param token /
|
||||||
*/
|
*/
|
||||||
public void logout(String token) {
|
public void logout(String token) {
|
||||||
String key = properties.getOnlineKey() + token;
|
String loginKey = tokenProvider.loginKey(token);
|
||||||
redisUtils.del(key);
|
redisUtils.del(loginKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,43 +137,13 @@ public class OnlineUserService {
|
||||||
return (OnlineUserDto)redisUtils.get(key);
|
return (OnlineUserDto)redisUtils.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测用户是否在之前已经登录,已经登录踢下线
|
|
||||||
* @param userName 用户名
|
|
||||||
*/
|
|
||||||
public void checkLoginOnUser(String userName, String igoreToken){
|
|
||||||
List<OnlineUserDto> onlineUserDtos = getAll(userName);
|
|
||||||
if(onlineUserDtos ==null || onlineUserDtos.isEmpty()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for(OnlineUserDto onlineUserDto : onlineUserDtos){
|
|
||||||
if(onlineUserDto.getUserName().equals(userName)){
|
|
||||||
try {
|
|
||||||
String token =EncryptUtils.desDecrypt(onlineUserDto.getKey());
|
|
||||||
if(StringUtils.isNotBlank(igoreToken)&&!igoreToken.equals(token)){
|
|
||||||
this.kickOut(token);
|
|
||||||
}else if(StringUtils.isBlank(igoreToken)){
|
|
||||||
this.kickOut(token);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("checkUser is error",e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据用户名强退用户
|
* 根据用户名强退用户
|
||||||
* @param username /
|
* @param username /
|
||||||
*/
|
*/
|
||||||
@Async
|
@Async
|
||||||
public void kickOutForUsername(String username) throws Exception {
|
public void kickOutForUsername(String username) {
|
||||||
List<OnlineUserDto> onlineUsers = getAll(username);
|
String loginKey = properties.getOnlineKey() + username + "*";
|
||||||
for (OnlineUserDto onlineUser : onlineUsers) {
|
redisUtils.scanDel(loginKey);
|
||||||
if (onlineUser.getUserName().equals(username)) {
|
|
||||||
String token =EncryptUtils.desDecrypt(onlineUser.getKey());
|
|
||||||
kickOut(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class UserCacheManager {
|
||||||
public JwtUserDto getUserCache(String userName) {
|
public JwtUserDto getUserCache(String userName) {
|
||||||
if (StringUtils.isNotEmpty(userName)) {
|
if (StringUtils.isNotEmpty(userName)) {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
Object obj = redisUtils.hget(LoginProperties.cacheKey, userName);
|
Object obj = redisUtils.get(LoginProperties.cacheKey + userName);
|
||||||
if(obj != null){
|
if(obj != null){
|
||||||
return (JwtUserDto)obj;
|
return (JwtUserDto)obj;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class UserCacheManager {
|
||||||
if (StringUtils.isNotEmpty(userName)) {
|
if (StringUtils.isNotEmpty(userName)) {
|
||||||
// 添加数据, 避免数据同时过期
|
// 添加数据, 避免数据同时过期
|
||||||
long time = idleTime + RandomUtil.randomInt(900, 1800);
|
long time = idleTime + RandomUtil.randomInt(900, 1800);
|
||||||
redisUtils.hset(LoginProperties.cacheKey, userName, user, time);
|
redisUtils.set(LoginProperties.cacheKey + userName, user, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public class UserCacheManager {
|
||||||
public void cleanUserCache(String userName) {
|
public void cleanUserCache(String userName) {
|
||||||
if (StringUtils.isNotEmpty(userName)) {
|
if (StringUtils.isNotEmpty(userName)) {
|
||||||
// 清除数据
|
// 清除数据
|
||||||
redisUtils.hdel(LoginProperties.cacheKey, userName);
|
redisUtils.del(LoginProperties.cacheKey + userName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,7 +56,7 @@ login:
|
||||||
# Redis用户登录缓存配置
|
# Redis用户登录缓存配置
|
||||||
user-cache:
|
user-cache:
|
||||||
# 存活时间/秒
|
# 存活时间/秒
|
||||||
idle-time: 7200
|
idle-time: 21600
|
||||||
# 验证码
|
# 验证码
|
||||||
login-code:
|
login-code:
|
||||||
# 验证码类型配置 查看 LoginProperties 类
|
# 验证码类型配置 查看 LoginProperties 类
|
||||||
|
@ -84,9 +84,9 @@ jwt:
|
||||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||||
token-validity-in-seconds: 14400000
|
token-validity-in-seconds: 14400000
|
||||||
# 在线用户key
|
# 在线用户key
|
||||||
online-key: online-token-
|
online-key: "online-token:"
|
||||||
# 验证码
|
# 验证码
|
||||||
code-key: code-key-
|
code-key: "captcha-code:"
|
||||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||||
detect: 1800000
|
detect: 1800000
|
||||||
# 续期时间范围,默认1小时,单位毫秒
|
# 续期时间范围,默认1小时,单位毫秒
|
||||||
|
|
|
@ -58,7 +58,7 @@ login:
|
||||||
# Redis用户登录缓存配置
|
# Redis用户登录缓存配置
|
||||||
user-cache:
|
user-cache:
|
||||||
# 存活时间/秒
|
# 存活时间/秒
|
||||||
idle-time: 7200
|
idle-time: 21600
|
||||||
# 验证码
|
# 验证码
|
||||||
login-code:
|
login-code:
|
||||||
# 验证码类型配置 查看 LoginProperties 类
|
# 验证码类型配置 查看 LoginProperties 类
|
||||||
|
@ -86,9 +86,9 @@ jwt:
|
||||||
# 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
# 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||||
token-validity-in-seconds: 7200000
|
token-validity-in-seconds: 7200000
|
||||||
# 在线用户key
|
# 在线用户key
|
||||||
online-key: online-token-
|
online-key: "online-token:"
|
||||||
# 验证码
|
# 验证码
|
||||||
code-key: code-key-
|
code-key: "captcha-code:"
|
||||||
# token 续期检查时间范围(默认30分钟,单位默认毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
# token 续期检查时间范围(默认30分钟,单位默认毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||||
detect: 1800000
|
detect: 1800000
|
||||||
# 续期时间范围,默认 1小时,这里单位毫秒
|
# 续期时间范围,默认 1小时,这里单位毫秒
|
||||||
|
|
Loading…
Reference in New Issue