最近在做前后端分离的新框架,选用了后端springboot+shiro,前端vue+elementUI,第一次搭SSM之外的非demo项目,尤其shiro更是之前从未接触,折腾了很多天,遇到很多问题,大部分能百度出来,剩下的非常费时的问题且称之为坑吧.
# 跨域
一大部分问题就是跨域造成的,本身vue-cli搭建的项目可以用
|
|
来解决开发环境跨域的问题,生产环境反正可以打包静态文件到springboot项目中直接跑.
而我还是脑抽得选择了强行跨域,假装自己要把静态文件单独放个服务器跑…为此遇到很多问题,折腾好几天.
因此强力推荐上面的方案,简单快捷地解决跨域!
如果生产环境真的需要跨域的话,再按下面方法设置
大部分跨域的配置都能百度搜出来:
axios要
withCredentials: true
用session而不用啥特殊的token之类的话,就不用
config.headers['X-Token'] = getToken()
,这句是vueAdmin-template 中带的,需要删掉.后端需要配置允许跨域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
@Configuration public class CorsConfig { private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址 corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头 corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法 corsConfiguration.setAllowCredentials(true); return corsConfiguration; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置 return new CorsFilter(source); } }
# shiro拦截ajax返回json
shiro拦截到需要登录而用户尚未的请求时,会重定向至 /login/auth (未配置时是login.jsp),而ajax是不允许重定向的,ajax会收到302错误码,报错
Failed to load http://localhost:8080/test: Redirect from ‘http://localhost:8080/test’ to ‘http://localhost:8080/login/auth’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:9528’ is therefore not allowed access.
因此我们需要对拦截器进行改造,不要它默认的重定向了,我们直接去response里把json写好输出给前端.
自定义filter,(因为我的后端全部返回json,所以这里不判断是否ajax了)
|
|
接下来就是最坑的地方了,拦截器的注入.
原本搜到的方法是在ShiroConfiguration类中注入.
|
|
结果自定义的拦截器把所有的请求都拦截了,直接无视了我设置的
|
|
各种百度,能搜到的相关的资料也就只有segmentfault的提问没解决,题主给我的回复也不能解决 , 百度知道提问的没解决 , 简书方案并不能解决 .
最终在某个百度结果的第三页找到这篇博客 ,博主对问题一步一步的排查分析,debug源码,最终知道
Springboot 先加载了我们自定义的 Filter,然后再加载了 ShiroFilter
解决方法: 在自定义的filter里加上下面的代码
|
|
在configration类里就不需要声明这个bean,只需要直接调用 filterMap.put("authc", new 自定义Filter());
# Access-Control-Allow-Origin
在上面的自定义filter里,
|
|
如果设置为*的话,前端虽然可以收到json,但还是会报错
Failed to load http://localhost:8080/test: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’. Origin ‘http://localhost:9528’ is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
不允许设置为通配符* .
虽然此处设置了"http://localhost:9528" 但是这种做法终究不合适.
百度继续搜到此博客
得到解决方法
|
|