Browse Source

feat:[登录] 只允许同时1个地方登录

master
memorylkf 3 weeks ago
parent
commit
dcb630c082
8 changed files with 82 additions and 6 deletions
  1. +1
    -1
      hxhq-auth/src/main/java/com/hxhq/auth/controller/TokenController.java
  2. +13
    -0
      hxhq-auth/src/main/java/com/hxhq/auth/form/LoginBody.java
  3. +25
    -1
      hxhq-auth/src/main/java/com/hxhq/auth/service/SysLoginService.java
  4. +4
    -0
      hxhq-auth/src/main/resources/bootstrap.yml
  5. +5
    -0
      hxhq-common/hxhq-common-core/src/main/java/com/hxhq/common/core/constant/CacheConstants.java
  6. +6
    -1
      hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/auth/AuthLogic.java
  7. +24
    -3
      hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/service/TokenService.java
  8. +4
    -0
      hxhq-modules/hxhq-system/src/main/resources/bootstrap.yml

+ 1
- 1
hxhq-auth/src/main/java/com/hxhq/auth/controller/TokenController.java View File

@ -36,7 +36,7 @@ public class TokenController
public R<?> login(@RequestBody LoginBody form) public R<?> login(@RequestBody LoginBody form)
{ {
// 用户登录 // 用户登录
LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword(),form.getForce());
// 获取登录token // 获取登录token
return R.ok(tokenService.createToken(userInfo)); return R.ok(tokenService.createToken(userInfo));
} }

+ 13
- 0
hxhq-auth/src/main/java/com/hxhq/auth/form/LoginBody.java View File

@ -17,6 +17,11 @@ public class LoginBody
*/ */
private String password; private String password;
/**
* 强制登录
*/
private Boolean force;
public String getUsername() public String getUsername()
{ {
return username; return username;
@ -36,4 +41,12 @@ public class LoginBody
{ {
this.password = password; this.password = password;
} }
public Boolean getForce() {
return force;
}
public void setForce(Boolean force) {
this.force = force;
}
} }

+ 25
- 1
hxhq-auth/src/main/java/com/hxhq/auth/service/SysLoginService.java View File

@ -1,6 +1,7 @@
package com.hxhq.auth.service; package com.hxhq.auth.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.hxhq.common.core.constant.CacheConstants; import com.hxhq.common.core.constant.CacheConstants;
import com.hxhq.common.core.constant.Constants; import com.hxhq.common.core.constant.Constants;
@ -40,9 +41,15 @@ public class SysLoginService
private RedisService redisService; private RedisService redisService;
/** /**
* 是否允许账户多终端同时登录true允许 false不允许
*/
@Value("${token.soloLogin}")
private boolean soloLogin;
/**
* 登录 * 登录
*/ */
public LoginUser login(String username, String password)
public LoginUser login(String username, String password,Boolean force)
{ {
// 用户名或密码为空 错误 // 用户名或密码为空 错误
if (StringUtils.isAnyBlank(username, password)) if (StringUtils.isAnyBlank(username, password))
@ -81,6 +88,23 @@ public class SysLoginService
LoginUser userInfo = userResult.getData(); LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser(); SysUser user = userResult.getData().getSysUser();
if (!soloLogin)
{
// 如果用户不允许多终端同时登录清除缓存信息
String userIdKey = CacheConstants.LOGIN_USERID_KEY + user.getUserId();
String userKey = redisService.getCacheObject(userIdKey);
if (StringUtils.isNotEmpty(userKey))
{
if(force==null || !force){
throw new ServiceException("exists");
}else{
redisService.deleteObject(userIdKey);
redisService.deleteObject(userKey);
}
}
}
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{ {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");

+ 4
- 0
hxhq-auth/src/main/resources/bootstrap.yml View File

@ -23,3 +23,7 @@ spring:
# 共享配置 # 共享配置
shared-configs: shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# token配置
token:
# 是否允许账户多终端同时登录(true允许 false不允许)
soloLogin: false

+ 5
- 0
hxhq-common/hxhq-common-core/src/main/java/com/hxhq/common/core/constant/CacheConstants.java View File

@ -56,4 +56,9 @@ public class CacheConstants
* 登录IP黑名单 cache key * 登录IP黑名单 cache key
*/ */
public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList"; public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList";
/**
* 登录用户编号 redis key
*/
public static final String LOGIN_USERID_KEY = "login_userid:";
} }

+ 6
- 1
hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/auth/AuthLogic.java View File

@ -51,7 +51,12 @@ public class AuthLogic
*/ */
public void logoutByToken(String token) public void logoutByToken(String token)
{ {
tokenService.delLoginUser(token);
LoginUser loginUser = getLoginUser(token);
if(loginUser!=null){
tokenService.delLoginUser(token,loginUser.getUserid());
}else{
tokenService.delLoginUser(token,null);
}
} }
/** /**

+ 24
- 3
hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/service/TokenService.java View File

@ -9,6 +9,7 @@ import com.hxhq.common.security.utils.SecurityUtils;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.hxhq.common.core.constant.CacheConstants; import com.hxhq.common.core.constant.CacheConstants;
import com.hxhq.common.core.constant.SecurityConstants; import com.hxhq.common.core.constant.SecurityConstants;
@ -44,6 +45,12 @@ public class TokenService
private final static Long TOKEN_REFRESH_THRESHOLD_MINUTES = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; private final static Long TOKEN_REFRESH_THRESHOLD_MINUTES = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
/** /**
* 是否允许账户多终端同时登录true允许 false不允许
*/
@Value("${token.soloLogin}")
private boolean soloLogin;
/**
* 创建令牌 * 创建令牌
*/ */
public Map<String, Object> createToken(LoginUser loginUser) public Map<String, Object> createToken(LoginUser loginUser)
@ -130,13 +137,16 @@ public class TokenService
/** /**
* 删除用户缓存信息 * 删除用户缓存信息
*/ */
public void delLoginUser(String token)
public void delLoginUser(String token, Long userId)
{ {
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));
} }
if (!soloLogin && StringUtils.isNotNull(userId)) {
String userIdKey = getUserIdKey(userId);
redisService.deleteObject(userIdKey);
}
} }
/** /**
@ -166,10 +176,21 @@ public class TokenService
// 根据uuid将loginUser缓存 // 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken()); String userKey = getTokenKey(loginUser.getToken());
redisService.setCacheObject(userKey, loginUser, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES); redisService.setCacheObject(userKey, loginUser, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);
if (!soloLogin)
{
// 缓存用户唯一标识防止同一帐号同时登录
String userIdKey = getUserIdKey(loginUser.getSysUser().getUserId());
redisService.setCacheObject(userIdKey, userKey, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES);
}
} }
private String getTokenKey(String token) private String getTokenKey(String token)
{ {
return ACCESS_TOKEN + token; return ACCESS_TOKEN + token;
} }
private String getUserIdKey(Long userId)
{
return CacheConstants.LOGIN_USERID_KEY + userId;
}
} }

+ 4
- 0
hxhq-modules/hxhq-system/src/main/resources/bootstrap.yml View File

@ -23,3 +23,7 @@ spring:
# 共享配置 # 共享配置
shared-configs: shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# token配置
token:
# 是否允许账户多终端同时登录(true允许 false不允许)
soloLogin: false

Loading…
Cancel
Save