This commit is contained in:
777
2025-11-18 12:53:40 +08:00
parent 7a2965c2f8
commit 53e3adb498
4 changed files with 177 additions and 4 deletions

View File

@@ -0,0 +1,12 @@
package com.ruoyi.cai.dto.app;
import lombok.Data;
import java.io.Serializable;
@Data
public class UploadFileResp implements Serializable {
private String token;
private String domain;
private String httpUrl;
}

View File

@@ -143,6 +143,7 @@ public enum SystemConfigEnum {
V12_XIAOCHENGXU_ORG_ID("gh_62790d4f9c57", "V12德商小程序原始id",SystemConfigGroupEnum.SYSTEM),
V12_XIAOCHENGXU_PATH("pages/zf/index?", "V12德商小程序页面路径",SystemConfigGroupEnum.SYSTEM),
V12_WX_APP_ID("wxae39c7eed3221d26", "微信开放平台ID",SystemConfigGroupEnum.SYSTEM),
UPLOAD_FILE_DOMAIN("http://127.0.0.1:8080", "文件上传域名服务器",SystemConfigGroupEnum.SYSTEM),
// 七牛云 ?imageView2/2/w/120/h/120
// 腾讯云 ?thumbnail=120y120&imageView
IM_ICON_SUFFIX("?thumbnail=120y120&imageView", "im头像后缀",SystemConfigGroupEnum.SYSTEM),

View File

@@ -0,0 +1,117 @@
package com.ruoyi.cai.util;
import com.esotericsoftware.minlog.Log;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class OfflineTokenManager {
// 加密密钥离线系统需保持一致建议16位字符
private static final String SECRET_KEY = "7ZxQ9kL2pF4sT5mR"; // 16位密钥
// 有效期2小时单位毫秒
private static final long VALID_DURATION = 3 * 60 * 60 * 1000;
/**
* 生成包含时间戳的token
* @param userId 用户标识(可替换为其他业务唯一标识)
* @return 加密后的token
* @throws Exception 加密异常
*/
public static String generateToken(String userId) throws Exception {
// 获取当前时间戳(毫秒)
long timestamp = System.currentTimeMillis();
// 拼接用户ID和时间戳格式userId:timestamp
String content = userId + ":" + timestamp;
// 加密并返回Base64编码的token
return encrypt(content);
}
/**
* 校验token有效性
* @param token 待校验的token
* @return 校验结果true-有效false-无效
*/
public static boolean validateToken(String token) {
try {
// 解密token
String decryptedContent = decrypt(token);
// 解析内容格式userId:timestamp
String[] parts = decryptedContent.split(":", 2);
if (parts.length != 2) {
return false; // 格式错误
}
// 提取时间戳并校验
long tokenTimestamp = Long.parseLong(parts[1]);
long currentTime = System.currentTimeMillis();
// 检查是否在有效期内(允许一定时间误差,避免时钟细微差异)
// return currentTime - tokenTimestamp <= VALID_DURATION && currentTime >= tokenTimestamp;
return currentTime - tokenTimestamp <= VALID_DURATION;
} catch (Exception e) {
// 解密失败或格式错误均视为无效
log.error("解析失败问题",e);
return false;
}
}
/**
* 从有效token中提取用户ID
* @param token 已通过校验的token
* @return 用户ID
* @throws Exception 解析异常
*/
public static String getUserIdFromToken(String token) throws Exception {
String decryptedContent = decrypt(token);
String[] parts = decryptedContent.split(":", 2);
return parts[0];
}
// AES加密
private static String encrypt(String content) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted);
}
// AES解密
private static String decrypt(String token) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(token));
return new String(decrypted, StandardCharsets.UTF_8);
}
// 测试示例
public static void main(String[] args) throws Exception {
// 生成token
// String userId = "system_user_123";
// String token = generateToken(userId);
// System.out.println("生成的token: " + token);
// 校验token立即校验
boolean isValid = validateToken("Kor2eFRylHp+3tP6xevf7fCeH0TvBJsXFPuxHWtFkss=");
System.out.println("token是否有效: " + isValid);
// 提取用户ID
// if (isValid) {
// String extractedUserId = getUserIdFromToken(token);
// System.out.println("从token中提取的用户ID: " + extractedUserId);
// }
// 模拟2小时后校验实际场景中无需此代码仅作测试
// Thread.sleep(VALID_DURATION + 1000);
// boolean isExpired = validateToken(token);
// System.out.println("2小时后token是否有效: " + isExpired);
}
}