过期验证

This commit is contained in:
Yuxuecheng 2025-01-22 23:49:27 +08:00
parent f1fe30920f
commit 108066fab2
9 changed files with 224 additions and 46 deletions

View File

@ -3,12 +3,14 @@ package com.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 启动程序
*
* @author ruoyi
*/
@EnableScheduling
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{

View File

@ -0,0 +1,64 @@
package com.ruoyi.web.controller.overdue;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.AES.AESExample;
import com.ruoyi.framework.constants.Constants;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author ruoyi
*/
@RestController
@RequestMapping
public class OverdueController {
@Resource
private AESExample aesExample;
@Resource
private RedisTemplate<String,String> redisTemplate;
@GetMapping("overdue")
private R<String> overdue(@RequestParam String activationCode) {
try {
String overdue = aesExample.decrypt(activationCode);
// 确保文件内容长度足够
if (overdue != null && overdue.length() >= 19) {
// 截取从第5个字符开始的14个字符
String timeString = overdue.substring(4, 18);
// 获取当前时间并转换为相同格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String currentTime = sdf.format(new Date());
// 比较时间
if (currentTime.compareTo(timeString) > 0) {
// 当前时间大于激活码中的时间返回激活码已经过期
return R.fail("激活码已过期");
}else {
//当前时间小于激活码中的时间时
FileWriter writer = new FileWriter(Constants.KEY_FILE_PATH);
// 写入文件内容
writer.write(activationCode);
writer.close();
redisTemplate.opsForValue().set("overdue", overdue);
}
} else {
return R.fail("激活码不正确");
}
} catch (Exception e) {
return R.fail("激活码不正确");
}
return R.ok("激活成功");
}
}

View File

@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login","/wxLogin", "/register","/registerSmsCode","/registerPhone", "/captchaImage").permitAll()
.antMatchers("/login","/wxLogin", "/register","/registerSmsCode","/registerPhone", "/captchaImage","/overdue").permitAll()
// 静态资源可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

View File

@ -0,0 +1,10 @@
package com.ruoyi.framework.constants;
public interface Constants {
// 加密算法
String ALGORITHM = "AES";
// 常量密钥
String SECRET_KEY = "jinanshandongdianliangxinxijishu";
//密钥存储文件地址
String KEY_FILE_PATH = "E:/overdue.txt";
}

View File

@ -1,8 +1,17 @@
package com.ruoyi.framework.interceptor;
import java.io.*;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.framework.AES.AESExample;
import com.ruoyi.framework.constants.Constants;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
@ -17,33 +26,104 @@ import com.ruoyi.common.utils.ServletUtils;
* @author ruoyi
*/
@Component
public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
{
public abstract class RepeatSubmitInterceptor implements HandlerInterceptor {
@Resource
private AESExample aesExample;
@Resource
private RedisTemplate<String,String> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
if (handler instanceof HandlerMethod)
{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 获取请求路径
String requestURI = request.getRequestURI();
// 如果请求路径不是 /overdue则执行过期检查逻辑
if (!"overdue".equals(requestURI.substring( requestURI.lastIndexOf('/') + 1))) {
String overdue = redisTemplate.opsForValue().get("overdue");
if (overdue == null) {
// 读取文件内容
overdue = readFileContent();
}
// 确保文件内容长度足够
if (overdue != null && overdue.length() >= 19) {
// 截取从第5个字符开始的14个字符
String timeString = overdue.substring(4, 18);
// 获取当前时间并转换为相同格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String currentTime = sdf.format(new Date());
// 比较时间
if (currentTime.compareTo(timeString) > 0) {
// 当前时间大于文件中的时间返回901错误码
AjaxResult ajaxResult = AjaxResult.error(901, "系统已经过期,请联系管理员");
ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
return false;
}
} else {
// 当前时间大于文件中的时间返回901错误码
AjaxResult ajaxResult = AjaxResult.error(901, "系统已经过期,请联系管理员");
ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
return false;
}
}
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
if (annotation != null)
{
if (this.isRepeatSubmit(request, annotation))
{
if (annotation != null) {
if (this.isRepeatSubmit(request, annotation)) {
AjaxResult ajaxResult = AjaxResult.error(annotation.message());
ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
return false;
}
}
return true;
}
else
{
} else {
return true;
}
}
/**
* 读取文件内容并返回解密后的字符串
*
* @return 文件内容
*/
private String readFileContent() {
String filePath = Constants.KEY_FILE_PATH;
File file = new File(filePath);
// 判断文件是否存在
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
System.err.println("创建文件失败");
e.printStackTrace();
}
}
StringBuilder content = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
String decrypt = null;
try {
decrypt = aesExample.decrypt(content.toString());
} catch (Exception e) {
throw new RuntimeException("验证程序错误,请检查");
}
redisTemplate.opsForValue().set("overdue", decrypt);
return decrypt;
}
/**
* 验证是否重复提交由子类实现具体的防重复提交的规则
*

View File

@ -40,16 +40,19 @@
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0",
"clipboard": "2.0.8",
"core-js": "3.25.3",
"core-js": "^3.40.0",
"cross-spawn": "^7.0.6",
"dayjs": "^1.11.9",
"echarts": "5.4.0",
"element-ui": "2.15.12",
"execa": "^9.5.2",
"file-saver": "2.0.5",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"nice-try": "^3.0.1",
"nprogress": "0.2.0",
"qrcodejs2": "0.0.2",
"quill": "1.3.7",

View File

@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register','/faCade','/cerebrum']
const whiteList = ['/login', '/register','/faCade','/cerebrum','/overdue']
router.beforeEach((to, from, next) => {
NProgress.start()

View File

@ -114,6 +114,11 @@ export const constantRoutes = [
meta: {title: 'cerebrum', icon: 'user'}
}
]
},
{
path: '/overdue',
component: () => import('@/views/overdue'),
hidden: true
}
]

View File

@ -78,7 +78,11 @@ service.interceptors.response.use(res => {
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
isRelogin.show = false;
store.dispatch('LogOut').then(() => {
location.href = '/index';
@ -94,6 +98,10 @@ service.interceptors.response.use(res => {
} else if (code === 601) {
Message({message: msg, type: 'warning'})
return Promise.reject('error')
} else if (code === 901) {
// 跳转到 overdue 页面
location.href = '/overdue';
return Promise.reject('使用期限已过,请联系管理员。');
} else if (code !== 200) {
Notification.error({title: msg})
return Promise.reject('error')
@ -118,9 +126,15 @@ service.interceptors.response.use(res => {
// 通用下载方法
export function download(url, params, filename, config) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
downloadLoadingInstance = Loading.service({
text: "正在下载数据,请稍候",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
})
return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }],
transformRequest: [(params) => {
return tansParams(params)
}],
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
responseType: 'blob',
...config