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) { export function listRole(query) {
return request({ return request({
url: '/system/role/list', url: '/system/role/list',
method: 'get', method: 'post',
params: query params: query
}) })
} }

View File

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

View File

@ -31,6 +31,7 @@ public class AjaxResult extends HashMap<String, Object>
SUCCESS(0), SUCCESS(0),
/** 警告 */ /** 警告 */
WARN(301), WARN(301),
UN_AUTH(401),
/** 错误 */ /** 错误 */
ERROR(500); ERROR(500);
private final int value; 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.kickout.KickoutSessionFilter;
import com.ruoyi.framework.shiro.web.filter.online.OnlineSessionFilter; 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.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.OnlineWebSessionManager;
import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler; import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
@ -312,6 +313,7 @@ public class ShiroConfig
filters.put("kickout", kickoutSessionFilter()); filters.put("kickout", kickoutSessionFilter());
// 注销成功,则跳转到指定页面 // 注销成功,则跳转到指定页面
filters.put("logout", logoutFilter()); filters.put("logout", logoutFilter());
filters.put("user", customUserFilter());
shiroFilterFactoryBean.setFilters(filters); shiroFilterFactoryBean.setFilters(filters);
// 所有请求需要认证 // 所有请求需要认证
@ -401,6 +403,16 @@ public class ShiroConfig
return kickoutSessionFilter; return kickoutSessionFilter;
} }
/**
*
*/
public CustomUserFilter customUserFilter()
{
CustomUserFilter customUserFilter = new CustomUserFilter();
customUserFilter.setLoginUrl(loginUrl);
return customUserFilter;
}
/** /**
* thymeleafshiro * thymeleafshiro
*/ */

View File

@ -2,6 +2,12 @@ package com.ruoyi.framework.shiro.web.filter;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; 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.session.SessionException;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -65,7 +71,15 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
{ {
log.error("logout fail.", ise); 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) 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);
}
}
}