后端采用 springboot+spring-security+oauth2开发
前台采用纯静态页面的形式开发。()
以此做到前后端分离。采用token的形式做无状态登录。为以后业务扩张的分布式扩展做准备。
前后端分离第一个要解决的是跨域问题。为此我再后台起了一个bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class ConfigurationBeans {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
sercurity配置也得加上这段代码
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.csrf()
.disable();
//下面是http其它配置项
}
附上ajax代码
var data = getData();
var auth = getToken();
var returnData = null;
$.ajax({
type: api.type,
url: webDomain + api.url,
data: data,
async: false,
contentType: false,
processData: false,
beforeSend : function(request) {
request.setRequestHeader("Authorization",auth);
},
success: function (result) {
console.log(2)
if (result.code == 200) {
returnData = successFunction(result);
} else {
alert(result.msg)
}
},
error: function (jqXHR) {
console.log(jqXHR)
alert("发生错误:" + jqXHR.status);
}
});
}
但是除了登录等不需要不需要token的接口,调用其它的接口都一脸懵逼的报找不到token异常,为此,我猜想是跨域配置时,我没有允许Authorization请求头放行。也就是上面这句Java代码配置不对:
corsConfiguration.addAllowedHeader("*");
我开始尝试重新配置这个addAllowedHeader:
corsConfiguration.addAllowedHeader("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
corsConfiguration.addAllowedHeader("Authorization,*");
corsConfiguration.addAllowedHeader("*,Authorization");
无一例外,失败了。重新审视一下问题,有没有可能是springsecurity的过滤器链的优先级比这个跨域过滤器的优先级高?
因为前台小弟等着对接,所以没那么多时间去考虑那么多,就采取了一种简单粗暴的形式去解决。来不及去深究真正原因,直接不采用bean的形式去做跨域处理,而采用实现filter的形式,并通过 Integer.MIN_VALUE 指定优先级最高。
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
@Configuration
@Order(Integer.MIN_VALUE)
@Slf4j
public class CustomCorsFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
log.info("Authorization={}",request.getHeader("Authorization"));
Enumeration<String> es = request.getHeaderNames();
String s = "";
while (es.hasMoreElements()){
s = es.nextElement()+","+s;
}
log.info(s);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}