CORS: mode kredensial adalah 'termasuk'

100

Ya, saya tahu apa yang Anda pikirkan - pertanyaan CORS lagi, tapi kali ini saya bingung.

Jadi untuk memulai, pesan kesalahan yang sebenarnya:

XMLHttpRequest tidak dapat memuat http: //localhost/Foo.API/token . Nilai header 'Access-Control-Allow-Origin' dalam respons tidak boleh berupa wildcard '*' saat mode kredensial permintaan adalah 'include' . Asal ' http: // localhost: 5000 ' oleh karena itu tidak diizinkan akses. Mode kredensial permintaan yang dimulai oleh XMLHttpRequest dikontrol oleh atribut withCredentials.

Saya tidak yakin apa yang dimaksud dengan mode kredensial adalah 'sertakan' ?

Jadi ketika saya melakukan permintaan di tukang pos, saya tidak mengalami kesalahan seperti itu:

masukkan deskripsi gambar di sini

Tetapi ketika saya mengakses permintaan yang sama melalui aplikasi web angularjs saya, saya bingung dengan kesalahan ini. Ini permintaan / tanggapan angualrjs saya. Seperti yang akan Anda lihat jawabannya adalah OK 200, tetapi saya masih menerima kesalahan CORS:

Permintaan dan Tanggapan Fiddler:

Gambar berikut menunjukkan permintaan dan respons dari front-end web ke API

Pemain biola

Jadi berdasarkan semua posting lain yang saya baca online, sepertinya saya melakukan hal yang benar, itulah mengapa saya tidak dapat memahami kesalahannya. Terakhir, berikut adalah kode yang saya gunakan dalam angualrjs (pabrik login):

masukkan deskripsi gambar di sini

Implementasi CORS di API - Tujuan referensi:

Metode 1 digunakan:

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);
    }
}

Metode 2 digunakan:

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

    ConfigureOAuth(app);

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

}

Terima kasih banyak sebelumnya!

Richard Bailey
sumber
gambar yang bagus, apa itu? Untuk menjawab pertanyaan Anda, jika Anda menyertakan autentikasi, respons access-control-allow-origin haruslah host (halaman browser) asal, tidak boleh *- jadi, sisi server melakukan kesalahan CORS - oh, dan tukang pos berfungsi karena ini bukan permintaan lintas sumber
Jaromanda X
@JaromandaX, terima kasih atas tanggapannya. Gambar menunjukkan permintaan / tanggapan serta menunjukkan tajuk yang dilewatkan. Anda mengajukan pertanyaan, jelas menyatakan bahwa itu tidak mencapai tujuannya ...
Richard Bailey
Komentar saya harus menjadi semua yang perlu Anda ketahui - tidak perlu melihat gambar
Jaromanda X
Jadi baru-baru ini saya memutuskan untuk menjauh dari cookie di api web saya dan lebih memilih menggunakan token. Saat saya menggunakan cookie, CORS saya berfungsi tanpa masalah. Jadi saya berjuang untuk memahami bagaimana CORS tidak diimplementasikan dengan benar di sisi server
Richard Bailey
1
jika Anda menyertakan autentikasi, access-control-allow-originresponsnya harus host (halaman browser) asal, tidak boleh*
Jaromanda X

Jawaban:

103

Masalahnya berasal dari kode Angular Anda:

Jika withCredentialsdisetel ke true, itu mencoba mengirim kredensial atau cookie bersama dengan permintaan. Karena itu berarti asal lain berpotensi mencoba melakukan permintaan yang diautentikasi, karakter pengganti ("*") tidak diizinkan sebagai header "Access-Control-Allow-Origin".

Anda harus menjawab secara eksplisit dengan asal yang membuat permintaan di header "Access-Control-Allow-Origin" untuk membuat ini berfungsi.

Saya akan merekomendasikan untuk secara eksplisit memasukkan ke daftar putih asal yang ingin Anda izinkan untuk membuat permintaan yang diautentikasi, karena hanya menanggapi dengan asal dari permintaan tersebut berarti bahwa setiap situs web tertentu dapat melakukan panggilan yang diautentikasi ke backend Anda jika pengguna kebetulan memiliki sesi yang valid.

Saya menjelaskan hal ini dalam artikel yang saya tulis beberapa waktu lalu.

Jadi Anda dapat menyetel withCredentialske false atau menerapkan daftar putih asal dan menanggapi permintaan CORS dengan asal yang valid setiap kali kredensial terlibat

geekonaut
sumber
3
Saya sedang mengerjakan aplikasi Angular 5 dengan TypeScript. Saya harus memberikan withCredentials sebagai true kalau tidak saya akan mendapatkan pengecualian Otorisasi Gagal. Bagaimana mengatasi ini dengan Kredensial: benar
Ziggler
@ Ziggler Saya memiliki situasi yang sama. Apakah Anda menemukan solusi?
Pavel
@ Ziggler Saya didenda solusi lihat jawaban saya.
Pavel
1
Saya masih mendapatkan kesalahan ini saat menggunakan WithCredentials = TRUE dan Access-Control-Allow-Origin = [' localhost: 4200'] , dan saya TIDAK menggunakan bintang * sehingga pesan kesalahan tidak masuk akal lagi. PESAN KESALAHAN: "Respons untuk permintaan preflight tidak lolos pemeriksaan kontrol akses: Nilai dari header 'Access-Control-Allow-Origin' dalam respons tidak boleh menjadi wildcard * ketika mode kredensial permintaan adalah 'include'. Origin Oleh karena itu, ' localhost: 4200 ' tidak diizinkan akses. Mode kredensial permintaan yang dimulai oleh XMLHttpRequest dikontrol oleh atribut withCredentials. "
mruanova
@mruanova apakah Anda yakin header Access-Control-Allow-Origin disetel dengan benar dalam permintaan? Sepertinya ada sesuatu yang dikirim dengan wildcard di suatu tempat
geekonaut
14

Jika Anda menggunakan middleware CORS dan ingin mengirim withCredentialsboolean true, Anda dapat mengkonfigurasi CORS seperti ini:

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

`

Ankur Kedia
sumber
11

Menyesuaikan CORS untuk Angular 5 dan Keamanan Musim Semi (solusi basis Cookie)

Di sisi Angular diperlukan menambahkan opsi bendera withCredentials: trueuntuk transportasi Cookie:

constructor(public http: HttpClient) {
}

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

Di sisi server Java diperlukan penambahan CorsConfigurationSourceuntuk konfigurasi kebijakan 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()...
    }
}

Metode configure(HttpSecurity http)secara default akan digunakan corsConfigurationSourceuntukhttp.cors()

Pavel
sumber
1

Jika membantu, saya menggunakan centrifuge dengan aplikasi reactjs saya, dan, setelah memeriksa beberapa komentar di bawah, saya melihat file pustaka centrifuge.js, yang dalam versi saya, memiliki cuplikan kode berikut:

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

Setelah saya menghapus tiga baris ini, aplikasi berfungsi dengan baik, seperti yang diharapkan.

Semoga membantu!

Gustavo Garcia
sumber
1

Jika Anda menggunakan .NET Core, Anda harus .AllowCredentials () saat mengkonfigurasi CORS di Startup.CS.

Di dalam ConfigureServices

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

services.AddMvc();

Kemudian di dalam Configure:

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

Bagi saya, itu secara khusus hanya opsi yang hilang. AllowCredentials () yang menyebabkan kesalahan yang Anda sebutkan. Sebagai catatan tambahan secara umum untuk orang lain yang memiliki masalah CORS juga, masalah urutan dan AddCors () harus didaftarkan sebelum AddMVC () di dalam kelas Startup Anda.

Steven Pfeifer
sumber