1. 修改 Shiro 認證失敗后默認重定向處理問題
a. 繼承需要使用的 ShiroFilter,重載 onAccessDenied() 方法:
@Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { Response result = Response.SUCCESS; result.setCode(EReturnCode.UNAUTHENTICATED.code()); result.setMsg(EReturnCode.UNAUTHENTICATED.message()); Gson gson = new Gson(); String json = gson.toJson(result);
HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.getWriter().write(json); return false; }
b. 在 Shiro 配置類中使用自定義配置:
/* * 1.定義ShiroFilterFactoryBean */ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 2.注冊SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 3.配置攔截器 Map<String, Filter> filterMap = new LinkedHashMap(); // 配置user攔截 filterMap.put("user", new ShiroUserFilter()); // 配置authc攔截 filterMap.put("authc", new ShiroAuthenticationFilter()); shiroFilterFactoryBean.setFilters(filterMap);
2. 跨域及 cookie 丟失問題
a. 前端創建 axios 實例時添加配置:
const service = axios.create({ baseURL: process.env.VUE_APP_BASE_BACKGROUND, // url = base url + request url withCredentials: true, // send cookies when cross-domain requests crossDomain: true, timeout: 5000 // request timeout })
b. 后端配置 CorsFilter 過濾器處理跨域問題,添加如下配置並把過濾器優先級調高:
/** * 為response設置header,實現跨域 * * @param servletRequest * @param servletResponse * @param filterChain * @throws IOException * @throws ServletException */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; // 指定本次預檢請求的有效期,單位為秒 response.setHeader("Access-Control-Max-Age", "1800"); // 防止亂碼,適用於傳輸JSON數據 response.setHeader("Content-Type","application/json;charset=UTF-8"); // 跨域的header設置 String method = request.getMethod(); response.setHeader("Access-Control-Allow-Methods", method); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); // 在訪問過來的時候檢測是否為OPTIONS請求,如果是就直接返回true(解決cookie丟失問題) if ("OPTIONS".equalsIgnoreCase(method)) { servletResponse.getOutputStream().write("Success".getBytes("utf-8")); } else { filterChain.doFilter(servletRequest, servletResponse); } }
參考文章:
https://www.cnblogs.com/chinaifae/p/10189312.html Access-Control-Max-Age 和 OPTION請求
https://blog.csdn.net/madonghyu/article/details/80027387 OPTION導致cookie丟失
https://blog.csdn.net/fifteen718/article/details/81127782 前后端分離傳遞cookie配置
https://blog.csdn.net/yao_1996/article/details/83510474 前后端分離傳遞sessionId