近期項目架構更新,前端統一使用vue架構,背景是SpringCloud系列搭建的微服務。前端統一通路的是zuul網關代理到Docker上的服務,在和前端開發人員調試時發現了問題。
最初背景配置的跨域支援為如下:
**
* 初始化相關配置
*/
@ControllerAdvice
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
ObjectMapper objectMapper = builder.build();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);// 忽略 transient 修飾的屬性
converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
super.configureMessageConverters(converters);
}
//這裡配置對前端跨域的支援
/**
* 跨域支援
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
}
}
這樣配置後,在調試階段前端不通過zuul網關直接通路docker上的服務是沒有問題的。
但是,在生産環境中docker上的服務是無法直接通路的,必須通過zuul網關代理,于是問題來了。。。
由于在zuul網關中是需要檢驗使用者的接口通路權限的,使用者在登陸成功後會得到JWT格式的token,然後在之後的所有請求中必須在RequestHeaders中攜帶token,用于後端校驗。
但是,前端vue在header中設定token後并沒有用,背景接收不到這個token。。。。
其實這就是浏覽器在作怪了,因為前端設定了自定義的請求頭,是以在正常請求之前浏覽器會先發送一個OPTIONS方式的請求用于驗證背景是否支援自定義請求頭。
由于後端并沒有設定對OPTIONS方式請求的支援是以拒絕了,知道了問題的原因後我們隻需要在背景的攔截器中加入判斷的代碼:
//如果是OPTIONS方式的請求直接通過
if ("OPTIONS".equals(request.getMethod())){
return true;
}
這樣背景就可以正常接收到前端攜帶的token了。