‘liusuyi’
2024-01-13 131b6c120db336ca5c2052b877be90ee201614db
增加账户互踢
已修改5个文件
162 ■■■■■ 文件已修改
ard-work/pom.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/pom.xml
@@ -76,6 +76,7 @@
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!-- 视频处理 -->
<!--        <dependency>-->
<!--            <groupId>org.bytedeco</groupId>-->
<!--            <artifactId>javacv-platform</artifactId>-->
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -139,4 +139,9 @@
     */
    public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
            "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
    /**
     * 登录用户编号 redis key
     */
    public static final String LOGIN_USERID_KEY = "login_userid:";
}
ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java
@@ -49,7 +49,9 @@
        {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
           // tokenService.delLoginUser(loginUser.getToken());
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken(), loginUser.getUser().getUserId());
            // 记录用户退出日志
            //国际化
            final String key = "language";
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,9 +1,9 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import com.ruoyi.rongcloud.service.RongCloudService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -36,6 +36,11 @@
 */
@Component
public class SysLoginService {
    // 是否允许账户多终端同时登录(true允许 false不允许)
    @Value("${token.soloLogin}")
    private boolean soloLogin;
    @Autowired
    private TokenService tokenService;
@@ -65,7 +70,6 @@
     */
    public String login(String username, String password, String code, String uuid) {
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        // 验证码开关
        if (captchaEnabled) {
@@ -92,7 +96,17 @@
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        if (!soloLogin)
        {
            // 如果用户不允许多终端同时登录,清除缓存信息
            String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId();
            String userKey = redisCache.getCacheObject(userIdKey);
            if (StringUtils.isNotEmpty(userKey))
            {
                redisCache.deleteObject(userIdKey);
                redisCache.deleteObject(userKey);
            }
        }
        getRongCloudToken(loginUser);
        // 生成token
        String token = tokenService.createToken(loginUser);
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
@@ -4,6 +4,7 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -27,8 +28,7 @@
 * @author ruoyi
 */
@Component
public class TokenService
{
public class TokenService {
    // 令牌自定义标识
    @Value("${token.header}")
    private String header;
@@ -40,6 +40,10 @@
    // 令牌有效期(默认30分钟)
    @Value("${token.expireTime}")
    private int expireTime;
    // 是否允许账户多终端同时登录(true允许 false不允许)
    @Value("${token.soloLogin}")
    private boolean soloLogin;
    protected static final long MILLIS_SECOND = 1000;
@@ -55,23 +59,18 @@
     *
     * @return 用户信息
     */
    public LoginUser getLoginUser(HttpServletRequest request)
    {
    public LoginUser getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            try
            {
        if (StringUtils.isNotEmpty(token)) {
            try {
                Claims claims = parseToken(token);
                // 解析对应的权限以及用户信息
                String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
                String userKey = getTokenKey(uuid);
                LoginUser user = redisCache.getCacheObject(userKey);
                return user;
            }
            catch (Exception e)
            {
            } catch (Exception e) {
            }
        }
        return null;
@@ -80,24 +79,40 @@
    /**
     * 设置用户身份信息
     */
    public void setLoginUser(LoginUser loginUser)
    {
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
        {
    public void setLoginUser(LoginUser loginUser) {
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
            refreshToken(loginUser);
        }
    }
    ///**
    // * 删除用户身份信息
    // */
    //public void delLoginUser(String token)
    //{
    //    if (StringUtils.isNotEmpty(token))
    //    {
    //        String userKey = getTokenKey(token);
    //        redisCache.deleteObject(userKey);
    //    }
    //}
    /**
     * 删除用户身份信息
     */
    public void delLoginUser(String token)
    {
        if (StringUtils.isNotEmpty(token))
        {
    public void delLoginUser(String token, String userId) {
        if (StringUtils.isNotEmpty(token)) {
            String userKey = getTokenKey(token);
            redisCache.deleteObject(userKey);
        }
        if (!soloLogin && StringUtils.isNotNull(userId)) {
            String userIdKey = getUserIdKey(userId);
            redisCache.deleteObject(userIdKey);
        }
    }
    private String getUserIdKey(String userId) {
        return Constants.LOGIN_USERID_KEY + userId;
    }
    /**
@@ -106,8 +121,7 @@
     * @param loginUser 用户信息
     * @return 令牌
     */
    public String createToken(LoginUser loginUser)
    {
    public String createToken(LoginUser loginUser) {
        String token = IdUtils.fastUUID();
        loginUser.setToken(token);
        setUserAgent(loginUser);
@@ -124,40 +138,67 @@
     * @param loginUser
     * @return 令牌
     */
    public void verifyToken(LoginUser loginUser)
    {
    public void verifyToken(LoginUser loginUser) {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
        {
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
            refreshToken(loginUser);
        }
    }
    ///**
    // * 刷新令牌有效期
    // *
    // * @param loginUser 登录信息
    // */
    //public void refreshToken(LoginUser loginUser)
    //{
    //    loginUser.setLoginTime(System.currentTimeMillis());
    //    String appUserType = loginUser.getUser().getAppUserType();
    //    if(StringUtils.isNull(appUserType))
    //    {
    //        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
    //        // 根据uuid将loginUser缓存
    //        String userKey = getTokenKey(loginUser.getToken());
    //        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
    //    }
    //    else
    //    {
    //        loginUser.setExpireTime(loginUser.getLoginTime() + 365*24*60 * MILLIS_MINUTE);
    //        // 根据uuid将loginUser缓存
    //        String userKey = getTokenKey(loginUser.getToken());
    //        redisCache.setCacheObject(userKey, loginUser, 365*24*60, TimeUnit.MINUTES);
    //    }
    //}
    /**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUser loginUser)
    {
    public void refreshToken(LoginUser loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        // 根据uuid将loginUser缓存
        //String userKey = getTokenKey(loginUser.getToken());
        //redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
        String appUserType = loginUser.getUser().getAppUserType();
        if(StringUtils.isNull(appUserType))
        {
        if (StringUtils.isNull(appUserType)) {
            loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
            // 根据uuid将loginUser缓存
            String userKey = getTokenKey(loginUser.getToken());
            redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
        }
        else
        {
            loginUser.setExpireTime(loginUser.getLoginTime() + 365*24*60 * MILLIS_MINUTE);
            if (!soloLogin) {
                // 缓存用户唯一标识,防止同一帐号,同时登录
                String userIdKey = getUserIdKey(loginUser.getUser().getUserId());
                redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
            }
        } else {
            loginUser.setExpireTime(loginUser.getLoginTime() + 365 * 24 * 60 * MILLIS_MINUTE);
            // 根据uuid将loginUser缓存
            String userKey = getTokenKey(loginUser.getToken());
            redisCache.setCacheObject(userKey, loginUser, 365*24*60, TimeUnit.MINUTES);
            redisCache.setCacheObject(userKey, loginUser, 365 * 24 * 60, TimeUnit.MINUTES);
        }
    }
    /**
@@ -165,8 +206,7 @@
     *
     * @param loginUser 登录信息
     */
    public void setUserAgent(LoginUser loginUser)
    {
    public void setUserAgent(LoginUser loginUser) {
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        loginUser.setIpaddr(ip);
@@ -181,8 +221,7 @@
     * @param claims 数据声明
     * @return 令牌
     */
    private String createToken(Map<String, Object> claims)
    {
    private String createToken(Map<String, Object> claims) {
        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
@@ -195,8 +234,7 @@
     * @param token 令牌
     * @return 数据声明
     */
    private Claims parseToken(String token)
    {
    private Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
@@ -209,8 +247,7 @@
     * @param token 令牌
     * @return 用户名
     */
    public String getUsernameFromToken(String token)
    {
    public String getUsernameFromToken(String token) {
        Claims claims = parseToken(token);
        return claims.getSubject();
    }
@@ -221,18 +258,15 @@
     * @param request
     * @return token
     */
    private String getToken(HttpServletRequest request)
    {
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(header);
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
        {
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
            token = token.replace(Constants.TOKEN_PREFIX, "");
        }
        return token;
    }
    private String getTokenKey(String uuid)
    {
    private String getTokenKey(String uuid) {
        return CacheConstants.LOGIN_TOKEN_KEY + uuid;
    }
}