feat(shiro): 添加自定义用户认证过滤器并优化登出逻辑

- 在 AjaxResult 中新增 UN_AUTH 状态码用于未授权提示
- 实现 CustomUserFilter 处理 H5 请求的未登录情况
- 修改 LogoutFilter 支持 H5 登录超时返回 JSON 提示
- 前端请求超时时间从10 秒调整为 120 秒- 登出后跳转路径由 /index 更改为 /login
- 角色列表接口请求方式由 get 改为 post- Shiro 配置中注册并启用自定义用户过滤器
dev_1.0.0
chenhao 2025-11-18 17:44:55 +08:00
parent b958e1f607
commit 3466208112
6 changed files with 65 additions and 5 deletions

View File

@ -4,7 +4,7 @@ import request from '@/utils/request'
export function listRole(query) {
return request({
url: '/system/role/list',
method: 'get',
method: 'post',
params: query
})
}

View File

@ -16,7 +16,7 @@ const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000,
timeout: 120*1000,
// 允许携带cookieSession认证必需
withCredentials: true
})
@ -84,8 +84,8 @@ service.interceptors.response.use(res => {
isRelogin.show = true
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false
store.dispatch('LogOut').then(() => {
location.href = '/index'
store.dispatch('FedLogOut').then(() => {
location.href = '/login'
})
}).catch(() => {
isRelogin.show = false

View File

@ -31,6 +31,7 @@ public class AjaxResult extends HashMap<String, Object>
SUCCESS(0),
/** 警告 */
WARN(301),
UN_AUTH(401),
/** 错误 */
ERROR(500);
private final int value;

View File

@ -36,6 +36,7 @@ import com.ruoyi.framework.shiro.web.filter.captcha.CaptchaValidateFilter;
import com.ruoyi.framework.shiro.web.filter.kickout.KickoutSessionFilter;
import com.ruoyi.framework.shiro.web.filter.online.OnlineSessionFilter;
import com.ruoyi.framework.shiro.web.filter.sync.SyncOnlineSessionFilter;
import com.ruoyi.framework.shiro.web.filter.user.CustomUserFilter;
import com.ruoyi.framework.shiro.web.session.OnlineWebSessionManager;
import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
@ -312,6 +313,7 @@ public class ShiroConfig
filters.put("kickout", kickoutSessionFilter());
// 注销成功,则跳转到指定页面
filters.put("logout", logoutFilter());
filters.put("user", customUserFilter());
shiroFilterFactoryBean.setFilters(filters);
// 所有请求需要认证
@ -401,6 +403,16 @@ public class ShiroConfig
return kickoutSessionFilter;
}
/**
*
*/
public CustomUserFilter customUserFilter()
{
CustomUserFilter customUserFilter = new CustomUserFilter();
customUserFilter.setLoginUrl(loginUrl);
return customUserFilter;
}
/**
* thymeleafshiro
*/

View File

@ -2,6 +2,12 @@ package com.ruoyi.framework.shiro.web.filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
@ -65,7 +71,15 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
{
log.error("logout fail.", ise);
}
issueRedirect(request, response, redirectUrl);
String xRequestedWith = ((HttpServletRequest) request).getHeader("X-Requested-With");
if (xRequestedWith!=null && xRequestedWith.contains("H5")) {
AjaxResult ajaxResult = new AjaxResult(AjaxResult.Type.UN_AUTH, "未登录或登录超时。请重新登录");
HttpServletResponse res = (HttpServletResponse) response;
ServletUtils.renderString(res, JSON.toJSONString(ajaxResult));
}else{
issueRedirect(request, response, redirectUrl);
}
}
catch (Exception e)
{

View File

@ -0,0 +1,33 @@
package com.ruoyi.framework.shiro.web.filter.user;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;
import com.alibaba.fastjson.JSON;
import org.apache.shiro.web.filter.authc.UserFilter;
/**
*
*/
public class CustomUserFilter extends UserFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
String xRequestedWith = ((HttpServletRequest) request).getHeader("X-Requested-With");
if (xRequestedWith!=null && xRequestedWith.contains("H5")) {
AjaxResult ajaxResult = new AjaxResult(AjaxResult.Type.UN_AUTH, "未登录或登录超时。请重新登录");
HttpServletResponse res = (HttpServletResponse) response;
ServletUtils.renderString(res, JSON.toJSONString(ajaxResult));
return false;
} else {
return super.onAccessDenied(request, response);
}
}
}