前后端分離項目中后台集成shiro需要注意的二三事


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

  https://segmentfault.com/q/1010000019774772 其它問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM