nnnn
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user