Sfoglia il codice sorgente

token 过期,最大分页限制

wangyunpeng 1 settimana fa
parent
commit
3b4f85fdb7

+ 37 - 0
api-module/src/main/java/com/tzld/piaoquan/api/config/JwtInterceptor.java

@@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.util.Base64;
+import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -265,6 +266,8 @@ public class JwtInterceptor implements HandlerInterceptor {
                 String key = TOKEN_PREFIX.replace("{token}", token);
                 String loginUserString = redisUtils.getString(key);
                 if (StringUtils.isBlank(loginUserString)) {
+                    // token 已过期,从列表中清理
+                    cleanExpiredToken(token);
                     return;
                 }
                 ContentPlatformAccount account = JSON.parseObject(loginUserString, ContentPlatformAccount.class);
@@ -285,6 +288,40 @@ public class JwtInterceptor implements HandlerInterceptor {
         });
     }
 
+    /**
+     * 触发清理:遍历该手机号的所有 token,移除已过期的
+     */
+    private void cleanExpiredToken(String token) {
+        try {
+            String telKey = "login.token.tel." + token;
+            String telNum = redisUtils.getString(telKey);
+            if (StringUtils.isBlank(telNum)) {
+                redisUtils.del(telKey);
+                return;
+            }
+            String listKey = "login.account.token.list." + telNum;
+            List<String> tokens = redisUtils.listRange(listKey);
+            if (tokens == null || tokens.isEmpty()) {
+                redisUtils.del(telKey);
+                return;
+            }
+            for (String t : tokens) {
+                if (StringUtils.isBlank(t)) {
+                    continue;
+                }
+                String loginKey = TOKEN_PREFIX.replace("{token}", t);
+                if (StringUtils.isBlank(redisUtils.getString(loginKey))) {
+                    // token 已过期,从列表和映射中移除
+                    redisUtils.listRemove(listKey, t);
+                    redisUtils.del("login.token.tel." + t);
+                    redisUtils.del("sign_key." + t);
+                }
+            }
+        } catch (Exception e) {
+            log.error("cleanExpiredToken error, token={}", token, e);
+        }
+    }
+
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception
             ex) throws Exception {

+ 9 - 2
api-module/src/main/java/com/tzld/piaoquan/api/model/param/PageParam.java

@@ -5,10 +5,9 @@ import lombok.Getter;
 import lombok.Setter;
 
 /**
- * 通用分页参数
+ * 通用分页参数,pageSize 最大 50
  */
 @Getter
-@Setter
 public class PageParam {
 
     @ApiModelProperty(value = "页码")
@@ -16,4 +15,12 @@ public class PageParam {
     @ApiModelProperty(value = "每页个数")
     private Integer pageSize = 20;
 
+    public void setPageNum(Integer pageNum) {
+        this.pageNum = pageNum;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = (pageSize != null && pageSize > 50) ? 50 : pageSize;
+    }
+
 }

+ 6 - 7
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformAccountServiceImpl.java

@@ -107,17 +107,14 @@ public class ContentPlatformAccountServiceImpl implements ContentPlatformAccount
 
     private void saveTokenToRedis(AccountLoginVO loginInfo, String oldToken, String token) {
         String tokenPrefix = "login.{token}";
-//        // 清除老token
-//        if (StringUtils.hasText(oldToken)) {
-//            String info = redisUtils.getString(tokenPrefix.replace("{token}", oldToken));
-//            if (StringUtils.hasText(info)) {
-//                redisUtils.del(tokenPrefix.replace("{token}", oldToken));
-//            }
-//        }
+        // 允许同一账号多端登录
         String redisKey = tokenPrefix.replace("{token}", token);
         redisUtils.setValueWithExpire(redisKey, JSON.toJSONString(loginInfo), 7 * 24 * 60 * 60L);
         String tokenListKey = "login.account.token.list." + loginInfo.getTelNum();
         redisUtils.listLeftPush(tokenListKey, token);
+        // 存 token → telNum 映射,用于 token 过期时从 list 中清理
+        String tokenTelKey = "login.token.tel." + token;
+        redisUtils.setValueWithExpire(tokenTelKey, loginInfo.getTelNum(), 7 * 24 * 60 * 60L);
     }
 
     @Override
@@ -194,6 +191,8 @@ public class ContentPlatformAccountServiceImpl implements ContentPlatformAccount
                 return;
             }
             redisUtils.del("login." + token);
+            redisUtils.del("login.token.tel." + token);
+            redisUtils.del("sign_key." + token);
         }
     }
 

+ 11 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformCooperateAccountServiceImpl.java

@@ -116,6 +116,10 @@ public class ContentPlatformCooperateAccountServiceImpl implements ContentPlatfo
             account.setCreateTimestamp(now);
             gzhAccountMapper.insertSelective(account);
         } else {
+            ContentPlatformGzhAccount existing = gzhAccountMapper.selectByPrimaryKey(param.getId());
+            if (!Objects.equals(loginAccount.getId(), existing.getCreateAccountId())) {
+                throw new CommonException(ExceptionEnum.PARAM_ERROR);
+            }
             account.setId(param.getId());
             account.setStatus(AccountStatusEnum.NORMAL.getVal());
             gzhAccountMapper.updateByPrimaryKeySelective(account);
@@ -164,6 +168,13 @@ public class ContentPlatformCooperateAccountServiceImpl implements ContentPlatfo
 
     @Override
     public void gzhDelete(Long id) {
+        ContentPlatformGzhAccount existing = gzhAccountMapper.selectByPrimaryKey(id);
+        if (Objects.isNull(existing)) {
+            return;
+        }
+        if (!Objects.equals(LoginUserContext.getUser().getId(), existing.getCreateAccountId())) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR);
+        }
         List<ContentPlatformGzhPlan> planList = planService.getGzhPlanListByCooperateAccountId(id);
         if (CollectionUtils.isNotEmpty(planList)) {
             throw new CommonException(ExceptionEnum.GZH_DELETE_PLAN_EXISTS);

+ 11 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformNoticeServiceImpl.java

@@ -1,6 +1,8 @@
 package com.tzld.piaoquan.api.service.contentplatform.impl;
 
+import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
 import com.tzld.piaoquan.api.common.enums.contentplatform.PlanStatusEnum;
+import com.tzld.piaoquan.api.common.exception.CommonException;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.ContentPlatformIllegalMsgMapper;
 import com.tzld.piaoquan.api.model.config.LoginUserContext;
 import com.tzld.piaoquan.api.model.param.contentplatform.NoticeListParam;
@@ -17,6 +19,7 @@ import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 @Slf4j
 @Service
@@ -60,6 +63,14 @@ public class ContentPlatformNoticeServiceImpl implements ContentPlatformNoticeSe
 
     @Override
     public void noticeRead(NoticeReadParam param) {
+        ContentPlatformAccount loginAccount = LoginUserContext.getUser();
+        ContentPlatformIllegalMsg msg = msgMapper.selectByPrimaryKey(param.getId());
+        if (Objects.isNull(msg)) {
+            return;
+        }
+        if (!Objects.equals(loginAccount.getId(), msg.getAccountId())) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR);
+        }
         ContentPlatformIllegalMsg illegalMsg = new ContentPlatformIllegalMsg();
         illegalMsg.setId(param.getId());
         illegalMsg.setStatus(1);

+ 9 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java

@@ -278,6 +278,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         if (Objects.isNull(plan)) {
             throw new CommonException(ExceptionEnum.GZH_PLAN_NOT_EXISTS);
         }
+        if (!Objects.equals(LoginUserContext.getUser().getId(), plan.getCreateAccountId())) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR);
+        }
         plan.setStatus(0);
         plan.setUpdateTimestamp(System.currentTimeMillis());
         gzhPlanMapper.updateByPrimaryKeySelective(plan);
@@ -312,6 +315,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         if (Objects.isNull(plan)) {
             throw new CommonException(ExceptionEnum.QW_PLAN_NOT_EXISTS);
         }
+        if (!Objects.equals(LoginUserContext.getUser().getId(), plan.getCreateAccountId())) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR);
+        }
         plan.setStatus(PlanStatusEnum.DELETED.getVal());
         plan.setUpdateTimestamp(System.currentTimeMillis());
         qwPlanMapper.updateByPrimaryKeySelective(plan);
@@ -357,6 +363,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
             planMapperExt.insertGzhPlanReturnId(gzhPlan);
         } else {
             ContentPlatformGzhPlan oldPlan = gzhPlanMapper.selectByPrimaryKey(param.getId());
+            if (!Objects.equals(LoginUserContext.getUser().getId(), oldPlan.getCreateAccountId())) {
+                throw new CommonException(ExceptionEnum.PARAM_ERROR);
+            }
             if (PublishStageEnum.USER.getVal() == param.getPublishStage()) {
                 if (StringUtils.hasText(oldPlan.getExternalId())) {
                     gzhPlan.setStagePublishStatus(0);

+ 7 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformUploadContentServiceImpl.java

@@ -27,6 +27,7 @@ import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -96,6 +97,9 @@ public class ContentPlatformUploadContentServiceImpl implements ContentPlatformU
         if (uploadVideo == null) {
             return null;
         }
+        if (!Objects.equals(user.getId(), uploadVideo.getCreateAccountId())) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR);
+        }
         if (StringUtils.isBlank(param.getTitle())
                 || StringUtils.isBlank(param.getCoverUrl())
                 || StringUtils.isBlank(param.getVideoUrl())) {
@@ -136,6 +140,9 @@ public class ContentPlatformUploadContentServiceImpl implements ContentPlatformU
         if (uploadVideo == null) {
             return;
         }
+        if (!Objects.equals(user.getId(), uploadVideo.getCreateAccountId())) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR);
+        }
         // 检查视频是否被引用
         if (checkVideoCited(uploadVideo)) {
             throw new CommonException(ExceptionEnum.VIDEO_CITED);

+ 14 - 0
common-module/src/main/java/com/tzld/piaoquan/growth/common/utils/RedisUtils.java

@@ -233,6 +233,20 @@ public class RedisUtils {
         return redisTemplate.opsForList().rightPop(key);
     }
 
+    /**
+     * 从列表中移除指定值,count=0 表示移除所有匹配项
+     */
+    public void listRemove(String key, String value) {
+        redisTemplate.opsForList().remove(key, 0, value);
+    }
+
+    /**
+     * 获取列表所有元素
+     */
+    public List<String> listRange(String key) {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
     public Double getDouble(String key) {
         try {
             String val = redisTemplate.opsForValue().get(key);