浏览代码

refreshtoken

superb 1 年之前
父节点
当前提交
937a246661

+ 14 - 3
controller/src/main/java/com/koobietech/eas/controller/AdminLoginController.java

@@ -1,22 +1,26 @@
 package com.koobietech.eas.controller;
 
 
+import com.koobietech.eas.common.pojo.JwtUserDto;
 import com.koobietech.eas.common.result.JsonResult;
 import com.koobietech.eas.dao.Pojo.AdminPojo;
 import com.koobietech.eas.dao.dto.LoginToken;
 import com.koobietech.eas.service.AdminLoginService;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 
+@Tag(name = "登陆模块")
 @RestController
 public class AdminLoginController {
     @Resource
     private AdminLoginService adminLoginService;
 
+
     @RequestMapping("/adminLogin")
+    @Operation(summary = "管理员登录",  description = "用户名和密码为请求载荷,若登录成功,返回两token")
     public JsonResult adminLogin(@RequestBody AdminPojo adminPojo){
 
         LoginToken result = adminLoginService.adminLogin(adminPojo);
@@ -24,5 +28,12 @@ public class AdminLoginController {
         return JsonResult.data(result);
     }
 
+    @PostMapping("/refreshToken")
+    @Operation(summary = "刷新token",  description = "当token过期,在请求头中携带refresh token,若刷新成功,返回新的token和refresh token")
+    public JsonResult refreshToken(@RequestHeader("Authorization") String refreshToken) {
+        // 返回新的token和refresh token
+        return JsonResult.data(adminLoginService.refreshToken(refreshToken));
+    }
+
 
 }

+ 10 - 5
security/src/main/java/com/koobietech/eas/security/filter/EasSecurityFilter.java

@@ -1,21 +1,25 @@
 package com.koobietech.eas.security.filter;
 
 import com.koobietech.eas.common.pojo.JwtUserDto;
+import com.koobietech.eas.common.result.JsonResult;
 import com.koobietech.eas.common.utils.JwtManager;
 import com.koobietech.eas.dao.adminLoginPojo.Permission;
 import com.koobietech.eas.dao.adminLoginPojo.UserDetail;
 import com.koobietech.eas.service.LoginRedisService;
+import org.springframework.http.*;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
 import org.springframework.web.filter.OncePerRequestFilter;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import javax.annotation.Resource;
 import javax.servlet.FilterChain;
@@ -32,12 +36,15 @@ public class EasSecurityFilter extends OncePerRequestFilter {
     @Resource
     JwtManager jwtManager;
 
+    @Resource
+    private RestTemplate restTemplate;
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
         //在这里添加Token判断
         System.out.println("EasSecurityFilter");
         //从请求里面拿到token
-        String token = request.getHeader(request.getHeader("Authorization"));
+        String token = request.getHeader("Authorization");
         //判断token是否存在
         if (StringUtils.hasText(token)) {
             //解析token成JwtUserDto
@@ -58,7 +65,7 @@ public class EasSecurityFilter extends OncePerRequestFilter {
                 ArrayList<SimpleGrantedAuthority> objects = new ArrayList<>();
 
                 // 遍历用户的权限列表
-                for (Permission adminPermission: permission) {
+                for (Permission adminPermission : permission) {
                     // 创建一个 SimpleGrantedAuthority 权限对象,并添加到集合中
                     SimpleGrantedAuthority authority = new SimpleGrantedAuthority(adminPermission.getDescription());
                     objects.add(authority);
@@ -70,10 +77,8 @@ public class EasSecurityFilter extends OncePerRequestFilter {
                 // 将身份验证令牌设置到当前的 SecurityContext 中
                 context.setAuthentication(authenticationToken);
             }
+            filterChain.doFilter(request, response);
         }
-
-        filterChain.doFilter(request, response);
     }
 
-
 }

+ 5 - 0
service/src/main/java/com/koobietech/eas/service/AdminLoginService.java

@@ -2,8 +2,13 @@ package com.koobietech.eas.service;
 
 import com.koobietech.eas.common.result.JsonResult;
 import com.koobietech.eas.dao.Pojo.AdminPojo;
+import com.koobietech.eas.dao.adminLoginPojo.UserDetail;
 import com.koobietech.eas.dao.dto.LoginToken;
 
 public interface AdminLoginService {
     LoginToken adminLogin(AdminPojo adminPojo);
+
+    LoginToken refreshToken(String refreshToken);
+
+
 }

+ 4 - 2
service/src/main/java/com/koobietech/eas/service/LoginRedisService.java

@@ -7,11 +7,13 @@ import com.koobietech.eas.dao.adminLoginPojo.UserDetail;
 public interface LoginRedisService {
     UserDetail checkToken(JwtUserDto jwtUserDto);
 
-    UserDetail checkRefreshToken(JwtUserDto jwtUserDto);
-
     void loginSaveCache(String redisTokenKey, UserDetail userDetailInRedis, Integer token_expires);
 
+    UserDetail loginGetCache(String newRedisTokenKey);
+
     String createJwtTokenKey(JwtUserDto jwtUserDto);
 
     String createJwtRefreshTokenKey(JwtUserDto jwtUserDto);
+
+    Boolean loginDeleteCache(String newRedisRefreshTokenKey);
 }

+ 45 - 24
service/src/main/java/com/koobietech/eas/service/impl/AdminLoginServiceImpl.java

@@ -1,13 +1,8 @@
 package com.koobietech.eas.service.impl;
 
-import com.koobietech.eas.common.config.MessageConfigProperties;
 import com.koobietech.eas.common.constant.UserType;
 import com.koobietech.eas.common.exception.EasException;
-import com.koobietech.eas.common.exception.InvalidUserException;
-import com.koobietech.eas.common.exception.NonUniqueResultException;
-import com.koobietech.eas.common.exception.PasswordIncorrectException;
 import com.koobietech.eas.common.pojo.JwtUserDto;
-import com.koobietech.eas.common.result.JsonResult;
 import com.koobietech.eas.common.utils.JwtManager;
 import com.koobietech.eas.common.utils.PasswordManager;
 import com.koobietech.eas.dao.Pojo.AdminPojo;
@@ -21,6 +16,7 @@ import com.koobietech.eas.service.AdminLoginService;
 import com.koobietech.eas.service.LoginRedisService;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
+
 import javax.annotation.Resource;
 import java.util.List;
 import java.util.Optional;
@@ -37,16 +33,18 @@ public class AdminLoginServiceImpl implements AdminLoginService {
     @Resource
     private EasSysUserinfoMapper easSysUserinfoMapper;
     @Resource
-    private MessageConfigProperties messageConfigProperties;
-    @Resource
     private LoginRedisService loginRedisService;
     @Resource
     private JwtManager jwtManager;
 
+    // token过期时间 单位:s
+    private final Integer token_expires = 30;
+    private final Integer refreshToken_expires = 60;
+
     @Override
     public LoginToken adminLogin(AdminPojo adminPojo) {
         if (adminPojo.getUsername() == null || adminPojo.getPasswd() == null || adminPojo.getUsername().isEmpty() || adminPojo.getPasswd().isEmpty()) {
-            throw new EasException("用户不存在", 509);
+            throw new EasException("用户不存在", 412);
         }
 
         try {
@@ -63,16 +61,12 @@ public class AdminLoginServiceImpl implements AdminLoginService {
             userDetailInRedis.setPermissions(adminLoginMapper.getUserPermissionsById(id));
             System.out.println("接收后" + userDetailInRedis);
 
-            // 先调用自定义sql查询用户详细信息、部门信息和权限信息
+            // 先调用自定义sql查询用户详细信息、部门信息  权限信息
             UserType userType = UserType.TEACHER;
             if (userDetailInRedis.getUsername().equals("admin")) {
                 userType = UserType.ADMIN;
             }
 
-            // token过期时间
-            Integer token_expires = 30;
-            Integer refreshToken_expires = 60;
-
             // 生成token
             JwtUserDto jwtUserDto = new JwtUserDto(userDetailInRedis.getUsername(), userDetailInRedis.getId(), userType);
             String token = jwtManager.createJwt(jwtUserDto, token_expires);
@@ -88,16 +82,41 @@ public class AdminLoginServiceImpl implements AdminLoginService {
 
             // 登录成功
             return new LoginToken(token, refreshToken);
-        } catch (InvalidUserException e) {
-            throw new EasException("用户不存在", 409);
-        } catch (NonUniqueResultException e) {
-            throw new EasException("用户不存在", 409);
-        } catch (PasswordIncorrectException e) {
-            throw new EasException("用户不存在", 409);
+        } catch (EasException e) {
+            throw new EasException("登录失败", 500);
+        }
+    }
+
+    @Override
+    public LoginToken refreshToken(String refreshToken) {
+        // 解析refresh token
+        JwtUserDto jwtUserDto = jwtManager.decodeJwt(refreshToken);
+
+        //生成新的 刷新k值 (refresh_token)
+        String newRedisRefreshTokenKey = loginRedisService.createJwtRefreshTokenKey(jwtUserDto);
+
+        //查询redis里面有没有这个k值
+        UserDetail userDetailInRedis = loginRedisService.loginGetCache(newRedisRefreshTokenKey);
+        if (userDetailInRedis == null) {
+            throw new EasException("refresh token已过期", 412);
         }
+        //如果不为空 那UserDetail里面就封装了用户的信息 生成新的token和refresh token
+        String newToken = jwtManager.createJwt(jwtUserDto, token_expires);
+        String newRefreshToken = jwtManager.createJwt(jwtUserDto, refreshToken_expires);
+
+        //生成新的k值 (token)
+        String newRedisTokenKey = loginRedisService.createJwtTokenKey(jwtUserDto);
+
+        // 更新Redis中的token和refresh token
+        loginRedisService.loginSaveCache(newRedisTokenKey, userDetailInRedis, token_expires);
+        loginRedisService.loginSaveCache(newRedisRefreshTokenKey, userDetailInRedis, refreshToken_expires);
+        return new LoginToken(newToken, newRefreshToken);
     }
 
-    private EasSysUserinfo findAdminByUsername(String username, String password) throws InvalidUserException, NonUniqueResultException, PasswordIncorrectException {
+
+
+
+    private EasSysUserinfo findAdminByUsername(String username, String password) throws EasException {
         EasSysUserinfoExample easSysUserinfoExample = new EasSysUserinfoExample();
         easSysUserinfoExample.createCriteria().andUsernameEqualTo(username);
         List<EasSysUserinfo> adminList = easSysUserinfoMapper.selectByExample(easSysUserinfoExample);
@@ -106,24 +125,26 @@ public class AdminLoginServiceImpl implements AdminLoginService {
         Optional<EasSysUserinfo> optionalAdmin = adminList.stream().findFirst();
 
         if (optionalAdmin.isEmpty()) {
-            throw new InvalidUserException();
+            throw new EasException("用户不存在", 409);
         }
         if (adminList.size() > 1) {
-            throw new NonUniqueResultException();
+            throw new EasException("用户不唯一", 410);
         }
 
         EasSysUserinfo easSysUserinfo = optionalAdmin.get();
+
+        // 验证密码 这个方法里面有解密 如果解密失败会抛出异常
         validatePassword(password, easSysUserinfo.getPasswd());
 
         return easSysUserinfo;
     }
 
-    private void validatePassword(String inputPassword, String encryptedPassword) throws PasswordIncorrectException {
+    private void validatePassword(String inputPassword, String encryptedPassword) throws EasException {
         String decryptedPassword = passwordManager.decryptPassword(inputPassword);
         System.out.println("前端解密来的decryptedPassword: " + decryptedPassword);
         System.out.println("数据库查到的密码easSysUserinfo.getPasswd(): " + encryptedPassword);
         if (!passwordEncoder.matches(decryptedPassword, encryptedPassword)) {
-            throw new PasswordIncorrectException();
+            throw new EasException("密码错误", 411);
         }
     }
 }

+ 18 - 7
service/src/main/java/com/koobietech/eas/service/impl/LoginRedisServiceImpl.java

@@ -8,11 +8,13 @@ import com.koobietech.eas.service.LoginRedisService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+
 @Service
 public class LoginRedisServiceImpl implements LoginRedisService {
 
     @Autowired
-    RedisService redisService;
+    private RedisService redisService;
 
 
     @Override
@@ -26,15 +28,19 @@ public class LoginRedisServiceImpl implements LoginRedisService {
     }
 
     @Override
-    public UserDetail checkRefreshToken(JwtUserDto jwtUserDto) {
-        String jwtKey = createJwtTokenKey(jwtUserDto);
-
-        return (UserDetail) redisService.get(jwtKey);
+    public void loginSaveCache(String redisTokenKey, UserDetail userDetailInRedis, Integer token_expires) {
+        redisService.set(redisTokenKey, userDetailInRedis, token_expires);
     }
 
+
     @Override
-    public void loginSaveCache(String redisTokenKey, UserDetail userDetailInRedis, Integer token_expires) {
-        redisService.set(redisTokenKey, userDetailInRedis, token_expires);
+    public UserDetail loginGetCache(String newRedisTokenKey) {
+        //看看redis里面有没有这个key
+        if (redisService.hasKey(newRedisTokenKey)) {
+            //有的话,就从redis里面取出来
+            return (UserDetail) redisService.get(newRedisTokenKey);
+        }
+        return null;
     }
 
     @Override
@@ -48,4 +54,9 @@ public class LoginRedisServiceImpl implements LoginRedisService {
         //根据jwtUserDto 生成jwtKey,格式为:eas_refresh_{id}_{username}_{type}
         return "eas_refresh_" + jwtUserDto.getId() + "_" + jwtUserDto.getUsername() + "_" + jwtUserDto.getType();
     }
+
+    @Override
+    public Boolean loginDeleteCache(String newRedisRefreshTokenKey) {
+        return redisService.del(newRedisRefreshTokenKey);
+    }
 }