spring boot + shiro + mybtis + vue 遇到的跨域问题

部署方式

spring boot 单独部署在一个tomcat中 端口号8090

vue 单独部署在另外一个tomcat中端口号 80;

导致跨域问题 ,接口无法访问

解决方案:(可能仅仅适用于我目前的这种方式spring boot + shiro + mybtis + vue)

参考:https://blog.csdn.net/weixin_42364816/article/details/86243337(感谢作者)

完全采用作者中的方式未能解决,在作者的基础上添加了一些信息

1.全部拷贝作者文中的方法

session过期后页面跳转问题

重写FormAuthenticationFilter类的onAccessDenied()方法,该方法是作为认证不通过时session的authc过滤器,如果跨域情况下:

   @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        HttpServletResponse httpResp = WebUtils.toHttp(response);
        HttpServletRequest httpReq = WebUtils.toHttp(request);
        /*系统重定向会默认把请求头清空,这里通过拦截器重新设置请求头,解决跨域问题*/
        httpResp.addHeader("Access-Control-Allow-Origin", httpReq.getHeader("Origin"));
        httpResp.addHeader("Access-Control-Allow-Headers", "*");
        httpResp.addHeader("Access-Control-Allow-Methods", "*");
        httpResp.addHeader("Access-Control-Allow-Credentials", "true");
        //该处的/toLogin在前端配置对应的跳转到登陆页面的方法即可
        httpResp.sendRedirect("/toLogin");
        return false;
    }

2.然后在shiroFilter中配置自定义的AuthenticationFilter类:

 @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        Map filters = shiroFilter.getFilters();
        //将自定义的AuthenticationFilter注入shiroFilter中,注意是authc过滤器
        filters.put("authc", new AuthenticationFilter());
        shiroFilter.setSecurityManager(securityManager);
        Map chain = new LinkedHashMap<>();
        chain.put("/login", "anon");
        chain.put("/toLogin", "anon");
        chain.put("/logout", "anon");
        chain.put("/page/401", "anon");
        chain.put("/page/403", "anon");
        chain.put("/page/index", "anon");
        chain.put("/**", "authc");
        shiroFilter.setLoginUrl("/auth/toLogin");
        shiroFilter.setUnauthorizedUrl("/unauth");
        shiroFilter.setFilterChainDefinitionMap(chain);
        return shiroFilter;
    }
3.前端需要做的

跨域请求无法传递cookie

先提供一种简便方法,即让axios能够跨域传Cookie:

import axios from 'axios';
 
//前端的axios添加withCredentials属性
axios.defaults.withCredentials=true;
Vue.prototype.$axios = axios

4.同时,CORS后台附一份: 

@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {

    //解决跨域
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration conf = new CorsConfiguration();
        conf.addAllowedHeader("*");
        conf.addAllowedMethod("*");
        conf.addAllowedOrigin("*");
        conf.setAllowCredentials(true);
        conf.setMaxAge(3600L);//秒
        conf.addExposedHeader("set-cookie");
        conf.addExposedHeader("access-control-allow-headers");
        conf.addExposedHeader("access-control-allow-methods");
        conf.addExposedHeader("access-control-allow-origin");
        conf.addExposedHeader("access-control-max-age");
        conf.addExposedHeader("X-Frame-Options");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", conf);
        return new CorsFilter(source);
    }

}
SpringBootApplication 中加入 
MapperScan扫描

到现在还没有完全解决我的问题

参考度娘 再添加一下代码

在springboot+shiro的项目中,这种问题的解决办法就是,让权限认证控制跳过OPTIONS方法,不让他做认证检查。shiro的过滤器可以自定义,在自定义的filter中,我们可以对onPreHandle这个方法做覆盖

@Override
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
        throws Exception {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    if (req.getMethod().equals(RequestMethod.OPTIONS.name())) {
        return true;
    }
    return super.onPreHandle(request, response, mappedValue);
}

你可能感兴趣的:(技术分享,工作心得)