From 0bf868d3cdf9226e178c076d3b588ed5207409a0 Mon Sep 17 00:00:00 2001
From: kongzy <kongzy>
Date: 星期五, 24 十一月 2023 17:51:40 +0800
Subject: [PATCH] merge

---
 assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysLoginService.java |   99 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysLoginService.java b/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysLoginService.java
new file mode 100644
index 0000000..a6676c0
--- /dev/null
+++ b/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysLoginService.java
@@ -0,0 +1,99 @@
+package com.gkhy.assess.framework.shiro.service;
+
+import com.gkhy.assess.common.constant.CacheConstant;
+import com.gkhy.assess.common.enums.UserStatusEnum;
+import com.gkhy.assess.common.exception.ApiException;
+import com.gkhy.assess.common.utils.JwtTokenUtil;
+import com.gkhy.assess.common.utils.RedisUtils;
+import com.gkhy.assess.system.domain.SysUser;
+import com.gkhy.assess.system.service.SysUserService;
+import com.gkhy.assess.system.utils.ShiroUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+@Component
+public class SysLoginService  {
+    @Autowired
+    private SysUserService sysUserService;
+    @Autowired
+    private SysPasswordService passwordService;
+    @Autowired
+    private RedisUtils redisUtils;
+
+    public SysUser login(String username, String password) {
+        SysUser sysUser=sysUserService.getUserByUsernamePhone(username);
+        validUser(sysUser);
+        passwordService.validate(sysUser,password);
+        recordLoginInfo(sysUser.getId());
+        return sysUser;
+    }
+
+    public void validUser(SysUser sysUser){
+        if(sysUser==null) {
+            throw new ApiException("用户不存在");
+        }
+        if(UserStatusEnum.DELETED.getCode().equals(sysUser.getDelFlag())){
+            throw new ApiException("用户已被删除");
+        }
+        if(UserStatusEnum.DISABLE.getCode().equals(sysUser.getStatus())){
+            throw new ApiException("用户已被停用");
+        }
+    }
+
+    public SysUser validJwtToken(String jwtToken){
+        String username= JwtTokenUtil.getUsername(jwtToken);
+        if(StringUtils.isEmpty(username)){
+            throw new AuthenticationException("token非法无效!");
+        }
+        SysUser sysUser=sysUserService.getUserByUsernamePhone(username);
+        validUser(sysUser);
+        if(!jwtTokenRefresh(jwtToken,username,sysUser.getPassword())){
+            throw new AuthenticationException("Token失效,请重新登录!");
+        }
+     //   setRolePermission(sysUser);
+        return sysUser;
+    }
+
+    /**
+     * JWTToken刷新生命周期 (实现: 用户在线操作不掉线功能)
+     * 1、登录成功后将用户的JWT生成的Token作为k、v存储到cache缓存里面(这时候k、v值一样),缓存有效期设置为Jwt有效时间的2倍
+     * 2、当该用户再次请求时,通过JWTFilter层层校验之后会进入到doGetAuthenticationInfo进行身份验证
+     * 3、当该用户这次请求jwt生成的token值已经超时,但该token对应cache中的k还是存在,则表示该用户一直在操作只是JWT的token失效了,程序会给token对应的k映射的v值重新生成JWTToken并覆盖v值,该缓存生命周期重新计算
+     * 4、当该用户这次请求jwt在生成的token值已经超时,并在cache中不存在对应的k,则表示该用户账户空闲超时,返回用户信息已失效,请重新登录。
+     * 注意: 前端请求Header中设置Authorization保持不变,校验有效性以缓存中的token为准。
+     *       用户过期时间 = Jwt有效时间 * 2。
+     *
+     * @param username
+     * @param passWord
+     * @return
+     */
+    public boolean jwtTokenRefresh(String jwtToken,String username,String passWord){
+        String key=redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+":"+JwtTokenUtil.md5Encode(jwtToken));
+        String cacheToken= (String) redisUtils.get(key);
+        if(StringUtils.isNotEmpty(cacheToken)){
+            // 校验token有效性
+            if(!JwtTokenUtil.verify(cacheToken,username,passWord)){
+                String newToken=JwtTokenUtil.sign(username,passWord);
+                // 设置超时时间
+                redisUtils.set(key,newToken);
+                redisUtils.expire(key,JwtTokenUtil.EXPIRATION*2/1000);
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    public void recordLoginInfo(Long userId){
+        SysUser user=new SysUser();
+        user.setId(userId);
+        user.setLoginIp(ShiroUtils.getIp());
+        user.setLoginDate(LocalDateTime.now());
+        sysUserService.updateById(user);
+
+    }
+}

--
Gitblit v1.9.2