CORS: режим облікових даних - "включити"


100

Так, я знаю, про що ти думаєш - ще одне запитання CORS, але цього разу я обдурений.

Отже, для початку, власне повідомлення про помилку:

XMLHttpRequest не може завантажити http: //localhost/Foo.API/token . Значення заголовка 'Access-Control-Allow-Origin' у відповіді не повинно бути символом підстановки '*', коли режим облікових даних запиту має значення "включати" . Отже, до джерела ' http: // localhost: 5000 ' заборонено доступ. Режим облікових даних запитів, ініційованих XMLHttpRequest, контролюється атрибутом withCredentials.

Я не впевнений, що мається на увазі під режимом облікових даних - "включати" ?

Тому, коли я виконую запит у листоноші, у мене не виникає такої помилки:

введіть тут опис зображення

Але коли я отримую доступ до того самого запиту через свою веб-програму angularjs, ця помилка мене вражає. Ось мій запит / відповідь angualrjs. Як ви побачите, відповідь є OK 200, але я все одно отримую помилку CORS:

Запит скрипта та відповідь:

Наступне зображення демонструє запит та відповідь веб-інтерфейсу на API

Скрипаль

Отже, виходячи з усіх інших дописів, які я читав в Інтернеті, здається, що я роблю правильно, тому я не можу зрозуміти помилку. Нарешті, ось код, який я використовую в angualrjs (фабрика входу):

введіть тут опис зображення

Впровадження CORS в API - Довідкові цілі:

Використаний метод 1:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("*", "*", "*")
        {
            SupportsCredentials = true
        };
        config.EnableCors(cors);
    }
}

Використаний метод 2:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

}

Заздалегідь велике спасибі!


приємні картинки, з чого вони? Щоб відповісти на ваше запитання, якщо ви включите автентифікацію, відповідь access-control-allow-origin повинна бути вихідним (сторінкою браузера) хостом, цього не може бути *- отже, сторона сервера робить CORS неправильно - о, і листоноша працює, тому що це не запит про перехресне походження
Jaromanda X

@JaromandaX, дякую за відповідь. Зображення демонструють запит / відповідь, а також демонструють передані заголовки. Ви ставите питання, очевидно, заявляєте, що воно не виконало своєї мети ...
Річард Бейлі,

Мій коментар повинен бути всім, що вам потрібно знати - не потрібно було бачити фотографії
Jaromanda X

Тож нещодавно я вирішив відійти від файлів cookie на своєму веб-API і скоріше скористатися маркерами. Коли я використовував файли cookie, мій CORS працює без будь-яких проблем. Тож я намагаюся зрозуміти, як CORS неправильно впроваджено на стороні сервера
Річард Бейлі,

1
якщо ви включаєте автентифікацію, access-control-allow-originвідповідь має бути*
вихідним

Відповіді:


103

Проблема випливає з вашого Angular коду:

Коли withCredentialsвстановлено значення true, він намагається надіслати облікові дані або файли cookie разом із запитом. Оскільки це означає, що інше походження потенційно намагається робити аутентифіковані запити, підстановка ("*") не дозволена як заголовок "Access-Control-Allow-Origin".

Вам доведеться явно відповісти на джерело, яке зробило запит, у заголовку "Access-Control-Allow-Origin", щоб зробити цю роботу.

Я б рекомендував чітко вказати білий список джерел, які ви хочете дозволити робити аутентифіковані запити, оскільки просто відповідь на джерело із запиту означає, що будь-який веб-сайт може робити аутентифіковані дзвінки до вашого серверного сервера, якщо користувач має дійсний сеанс.

Я пояснюю це у цій статті, яку я писав деякий час тому.

Таким чином, ви можете або встановити withCredentialsзначення false, або застосувати білий список походження та відповідати на запити CORS дійсним походженням, коли залучаються облікові дані


3
Я працюю над програмою Angular 5 із TypeScript. Мені потрібно вказати withCredentials як true, інакше я отримаю виняток Authorization Failed Як це вирішити за допомогою облікових даних: правда
Зігглер

@Ziggler У мене була та сама ситуація. Ви знаходите рішення?
Павло

@Ziggler Я оштрафував рішення, див. Мою відповідь.
Павло

1
Я все ще отримую цю помилку під час використання WithCredentials = TRUE та Access-Control-Allow-Origin = [' localhost: 4200'] , і я НЕ використовую зірку *, тому повідомлення про помилку більше не має сенсу. ПОВІДОМЛЕННЯ ПРО ПОМИЛКУ: "Відповідь на попередній запит не проходить перевірку контролю доступу: Значення заголовка" Access-Control-Allow-Origin "у відповіді не повинно бути символом підстановки *, коли режим облікових даних запиту має значення" include ". Тому " localhost: 4200 " не має доступу. Режим облікових даних запитів, ініційованих XMLHttpRequest, контролюється атрибутом withCredentials.
mruanova

@mruanova, ти впевнений, що в запиті правильно встановлено заголовок Access-Control-Allow-Origin? Здається, щось кудись надсилають із
узагальнюючим

14

Якщо ви використовуєте проміжне програмне забезпечення CORS і хочете надіслати withCredentialsлогічне значення true, ви можете налаштувати CORS таким чином:

var cors = require('cors');    
app.use(cors({credentials: true, origin: 'http://localhost:5000'}));

`


11

Налаштування CORS для Angular 5 та Spring Security (базове рішення cookie)

На кутовій стороні потрібно додати прапорець опції withCredentials: trueдля транспортування файлів cookie:

constructor(public http: HttpClient) {
}

public get(url: string = ''): Observable<any> {
    return this.http.get(url, { withCredentials: true });
}

На стороні сервера Java потрібно додати CorsConfigurationSourceдля конфігурації політику CORS:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        // This Origin header you can see that in Network tab
        configuration.setAllowedOrigins(Arrays.asList("http:/url_1", "http:/url_2")); 
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowedHeaders(Arrays.asList("content-type"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
}

Метод configure(HttpSecurity http)за замовчуванням використовуватиметься corsConfigurationSourceдляhttp.cors()


1

Якщо це допомагає, я використовував центрифугу з моєю програмою responsejs, і, перевіривши деякі коментарі нижче, я переглянув файл бібліотеки centrifuge.js, який у моїй версії мав такий фрагмент коду:

if ('withCredentials' in xhr) {
 xhr.withCredentials = true;
}

Після того, як я видалив ці три рядки, програма працювала нормально, як і слід було очікувати.

Сподіваюся, це допоможе!


1

Якщо ви використовуєте .NET Core, вам доведеться .AllowCredentials () під час налаштування CORS у Startup.CS.

Всередині ConfigureServices

services.AddCors(o => {
    o.AddPolicy("AllowSetOrigins", options =>
    {
        options.WithOrigins("https://localhost:xxxx");
        options.AllowAnyHeader();
        options.AllowAnyMethod();
        options.AllowCredentials();
    });
});

services.AddMvc();

Потім всередині Configure:

app.UseCors("AllowSetOrigins");
app.UseMvc(routes =>
    {
        // Routing code here
    });

Для мене конкретно просто бракувало опцій. AllowCredentials (), що спричинило згадану вами помилку. Як додаткове зауваження в цілому для інших, хто також має проблеми з CORS, порядок має значення та AddCors () повинні бути зареєстровані перед AddMVC () всередині вашого класу Startup.


0

Просто додайте Axios.defaults.withCredentials=trueзамість ( {credentials: true}) на стороні клієнта та змініть app.use(cors())на

app.use(cors(
  {origin: ['your client side server'],
  methods: ['GET', 'POST'],
  credentials:true,
}
))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.