Что такое междоменный домен?
Определение: Браузер запрашивает что-то с веб-страницы одного доменного имени под другим доменным именем. С точки зрения непрофессионала, браузеру не разрешено напрямую обращаться к ресурсам в домене B из домена A. Если вы хотите получить доступ, вам нужно выполнить один шаг, который называется «междоменный». Например, на странице Baidu вы нажимаете кнопку и запрашиваете у Sina интерфейс, который является междоменным. Отличается не только доменное имя, оно междоменное, но и доменное имя, порт и протокол разные, а ресурс запроса должен быть междоменным.
Почему междоменный?
Почему вам нужно пересекать домены вместо прямого доступа к ресурсам в других доменах? Это ограничение браузера Профессионально это называется ограничением политики браузера того же происхождения. В основном из соображений безопасности. В текущей структуре безопасности, когда обычно делается запрос, токен не хранится в заголовке.Если вы используете этот токен для обычного доступа к вещам в домене A, проблем нет, а затем вы переходите в домен B, и результат неверный.Если вы все еще носите этот токен, то домен B или веб-сайт B может взять ваш токен и перейти к домену A, чтобы сделать что-то, что довольно опасно. Таким образом, браузеры добавляют так называемые ограничения политики браузера того же происхождения. Но для того, чтобы действительно получить доступ к ресурсам B из домена A (обычный доступ), нам нужно использовать междоменный доступ, чтобы преодолеть этот предел.
SpringBoot решает междоменные проблемы
SpringBoot может решать междоменные проблемы на основе Cors.Cors — это механизм, который сообщает нашему бэкенду, какие сторонние (исходные) запросы могут обращаться к данным сервера.
Глобальная конфигурация
Пример конфигурации выглядит следующим образом:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
}
Во-первых, реализован интерфейс WebMvcConfigurer.Интерфейс WebMvcConfigurer очень мощный, и в нем много доступных методов.В SpringBoot2.0 можно решить некоторые задачи WebMvcConfigurerAdapter. Одним из методов является addCorsMappings(), представляющий собой интерфейс, специально разработанный разработчиками для решения междоменных проблем. Параметр построения — CorsRegistry.
Взгляните на исходный код CorsRegistry, это очень просто:
public class CorsRegistry {
private final List<CorsRegistration> registrations = new ArrayList<>();
public CorsRegistration addMapping(String pathPattern) {
CorsRegistration registration = new CorsRegistration(pathPattern);
this.registrations.add(registration);
return registration;
}
protected Map<String, CorsConfiguration> getCorsConfigurations() {
Map<String, CorsConfiguration> configs = new LinkedHashMap<>(this.registrations.size());
for (CorsRegistration registration : this.registrations) {
configs.put(registration.getPathPattern(), registration.getCorsConfiguration());
}
return configs;
}
}
Видно, что CorsRegistry имеет атрибут Registrations, который можно настроить в соответствии с разными путями проекта, но в нашем примере pathPattern напрямую устанавливается в /**, что означает, что все пути проекта были покрыты, и требуется только один CorsRegistration. быть созданным. . getCorsConfigurations(), этот метод предназначен для получения коллекции Map всех CorsConfigurations, а значением ключа является входящий путь pathPattern.
Возвращаясь к примеру кода CorsConfig, после добавления входящего пути pathPattern в объект реестра addMapping() он возвращает объект CorsRegistration, который предназначен для дополнительной настройки.Взгляните на код CorsRegistration, чтобы увидеть, что мы можем настроить?
public class CorsRegistration {
//传入的路径
private final String pathPattern;
//配置信息实体类
private final CorsConfiguration config;
//构造方法
public CorsRegistration(String pathPattern) {
this.pathPattern = pathPattern;
//原生注释看到了一个 @CrossOrigin 这个注解,待会看看是什么
// Same implicit default values as the @CrossOrigin annotation + allows simple methods
this.config = new CorsConfiguration().applyPermitDefaultValues();
}
//允许哪些源网站访问,默认所有
public CorsRegistration allowedOrigins(String... origins) {
this.config.setAllowedOrigins(Arrays.asList(origins));
return this;
}
//允许何种方式访问,默认简单方式,即:GET,HEAD,POST
public CorsRegistration allowedMethods(String... methods) {
this.config.setAllowedMethods(Arrays.asList(methods));
return this;
}
//设置访问header,默认所有
public CorsRegistration allowedHeaders(String... headers) {
this.config.setAllowedHeaders(Arrays.asList(headers));
return this;
}
//设置response headers,默认没有(什么都不设置)
public CorsRegistration exposedHeaders(String... headers) {
this.config.setExposedHeaders(Arrays.asList(headers));
return this;
}
//是否浏览器应该发送credentials,例如cookies Access-Control-Allow-Credentials
public CorsRegistration allowCredentials(boolean allowCredentials) {
this.config.setAllowCredentials(allowCredentials);
return this;
}
//设置等待时间,默认1800秒
public CorsRegistration maxAge(long maxAge) {
this.config.setMaxAge(maxAge);
return this;
}
protected String getPathPattern() {
return this.pathPattern;
}
protected CorsConfiguration getCorsConfiguration() {
return this.config;
}
}
локальная конфигурация
Я только что наткнулся на аннотацию @CrossOrigin, что она делает?
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
@Deprecated
String[] DEFAULT_ORIGINS = { "*" };
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
@Deprecated
String[] DEFAULT_ALLOWED_HEADERS = { "*" };
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
@Deprecated
boolean DEFAULT_ALLOW_CREDENTIALS = false;
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
@Deprecated
long DEFAULT_MAX_AGE = 1800
/**
* Alias for {@link #origins}.
*/
@AliasFor("origins")
String[] value() default {};
@AliasFor("value")
String[] origins() default {};
String[] allowedHeaders() default {};
String[] exposedHeaders() default {};
RequestMethod[] methods() default {};
String allowCredentials() default "";
long maxAge() default -1;
}
Эту аннотацию можно применить к методам или классам для достижения локального междоменного.Вы обнаружите, что за исключением установки пути (потому что это не обязательно, он локализован) другие параметры аналогичны глобальному.
резюме
SpringBoot может решать междоменные проблемы на основе Cors.Он может установить глобальный кросс-доменный, а также может достичь локального кросс-доменного.Гибкая конфигурация удобна для использования.