CORS: โหมดข้อมูลรับรองคือ 'รวม'


100

ใช่ฉันรู้ว่าคุณกำลังคิดอะไร - ยังเป็นคำถาม CORS อีกคำถาม แต่คราวนี้ฉันนิ่งงัน

ดังนั้นในการเริ่มต้นข้อความแสดงข้อผิดพลาดจริง:

XMLHttpRequest ไม่สามารถโหลดhttp: //localhost/Foo.API/token ค่าของ 'การเข้าถึงการควบคุมอนุญาตให้-กำเนิด' หัวในการตอบสนองจะต้องไม่เป็นสัญลักษณ์แทน '*' เมื่อมีการร้องขอของโหมดข้อมูลประจำตัวคือ 'รวมถึง' Origin ' http: // localhost: 5000 ' จึงไม่อนุญาตให้เข้าถึง โหมดหนังสือรับรองของคำขอที่เริ่มต้นโดย XMLHttpRequest ถูกควบคุมโดยแอตทริบิวต์ withCredentials

ฉันไม่แน่ใจว่าโหมดข้อมูลรับรองหมายถึงอะไรคือ 'รวม' ?

ดังนั้นเมื่อฉันดำเนินการตามคำขอในบุรุษไปรษณีย์ฉันไม่พบข้อผิดพลาดดังกล่าว:

ป้อนคำอธิบายภาพที่นี่

แต่เมื่อฉันเข้าถึงคำขอเดียวกันผ่านเว็บแอป angularjs ฉันรู้สึกสะดุดกับข้อผิดพลาดนี้ นี่คือคำขอ / การตอบกลับ angualrjs ของฉัน ดังที่คุณจะเห็นการตอบสนองOK 200แต่ฉันยังคงได้รับข้อผิดพลาด CORS:

คำขอและการตอบกลับของ Fiddler:

ภาพต่อไปนี้แสดงคำขอและการตอบกลับจากส่วนหน้าเว็บไปยัง 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);

}

ขอบคุณมากล่วงหน้า!


รูปสวย ๆ มีอะไรบ้าง? ในการตอบคำถามของคุณหากคุณรวมการรับรองความถูกต้องการตอบสนองที่อนุญาต - การควบคุมการเข้าถึงจะต้องเป็นโฮสต์ต้นทาง (หน้าเบราว์เซอร์) จึงเป็นไปไม่ได้*- ดังนั้นฝั่งเซิร์ฟเวอร์กำลังทำ CORS ผิด - โอ้และบุรุษไปรษณีย์ก็ทำงานได้เนื่องจาก ไม่ใช่คำขอข้ามแหล่งกำเนิด
Jaromanda X

@JaromandaX ขอบคุณสำหรับการตอบรับ รูปภาพแสดงการร้องขอ / การตอบกลับรวมทั้งแสดงให้เห็นถึงส่วนหัวที่ส่งผ่าน คุณถามคำถามชัดเจนว่ามันไม่บรรลุเป้าหมาย ...
Richard Bailey

ความคิดเห็นของฉันควรเป็นสิ่งที่คุณต้องรู้ - ไม่จำเป็นต้องดูรูปภาพ
Jaromanda X

เมื่อเร็ว ๆ นี้ฉันตัดสินใจที่จะย้ายออกจากคุกกี้บนเว็บ API และใช้โทเค็นแทน เมื่อฉันใช้คุกกี้ CORS ของฉันจะทำงานได้โดยไม่มีปัญหาใด ๆ ดังนั้นฉันจึงพยายามที่จะเข้าใจว่า CORS ไม่ได้ติดตั้งอย่างถูกต้องบนฝั่งเซิร์ฟเวอร์อย่างไร
Richard Bailey

1
หากคุณรวมการรับรองความถูกต้องการaccess-control-allow-originตอบสนองจะต้องเป็นโฮสต์ต้นทาง (หน้าเบราว์เซอร์) จะไม่สามารถเป็นได้*
Jaromanda X

คำตอบ:


103

ปัญหาเกิดจากรหัสเชิงมุมของคุณ:

เมื่อwithCredentialsตั้งค่าเป็นจริงจะพยายามส่งข้อมูลรับรองหรือคุกกี้ไปพร้อมกับคำขอ เนื่องจากนั่นหมายความว่าต้นทางอื่นอาจพยายามส่งคำขอที่ตรวจสอบสิทธิ์แล้วจึงไม่อนุญาตให้ใช้สัญลักษณ์แทน ("*") เป็นส่วนหัว "Access-Control-Allow-Origin"

คุณจะต้องตอบอย่างชัดเจนกับต้นทางที่ส่งคำขอในส่วนหัว "Access-Control-Allow-Origin" เพื่อให้ทำงาน

ฉันขอแนะนำให้เพิ่มรายการต้นทางที่คุณต้องการอนุญาตให้ทำคำขอที่ได้รับการรับรองความถูกต้องอย่างชัดเจนเนื่องจากเพียงแค่ตอบสนองด้วยจุดเริ่มต้นจากคำขอหมายความว่าเว็บไซต์ใดก็ตามสามารถทำการโทรที่ได้รับการรับรองความถูกต้องไปยังแบ็กเอนด์ของคุณหากผู้ใช้มีเซสชันที่ถูกต้อง

ฉันอธิบายสิ่งนี้ในบทความนี้ที่ฉันเขียนมาสักพักแล้ว

ดังนั้นคุณสามารถตั้งค่าwithCredentialsเป็นเท็จหรือใช้รายการต้นทางที่อนุญาตและตอบสนองต่อคำขอ CORS ด้วยต้นทางที่ถูกต้องเมื่อใดก็ตามที่ข้อมูลรับรองเกี่ยวข้อง


3
ฉันกำลังทำงานกับแอพพลิเคชั่น Angular 5 กับ TypeScript ฉันต้องให้ withCredentials เป็นจริงฉันจะได้รับข้อยกเว้น Authorization Failed วิธีแก้ปัญหานี้ด้วยข้อมูลประจำตัว: จริง
Ziggler

@ Ziggler ฉันมีสถานการณ์เดียวกัน คุณพบวิธีแก้ปัญหาหรือไม่?
พาเวล

@ Ziggler ฉันปรับวิธีแก้ปัญหาดูคำตอบของฉัน
Pavel

1
ฉันยังคงได้รับข้อผิดพลาดนี้เมื่อใช้ WithCredentials = TRUE และ Access-Control-Allow-Origin = [' localhost: 4200']และฉันไม่ได้ใช้ star * ดังนั้นข้อความแสดงข้อผิดพลาดจึงไม่สมเหตุสมผลอีกต่อไป ข้อความแสดงข้อผิดพลาด: "การตอบสนองต่อคำขอ preflight ไม่ผ่านการตรวจสอบการควบคุมการเข้าถึง: ค่าของส่วนหัว" Access-Control-Allow-Origin "ในการตอบกลับต้องไม่ใช่สัญลักษณ์แทน * เมื่อโหมดข้อมูลรับรองของคำขอเป็น" รวม " ' localhost: 4200 ' จึงไม่ได้รับอนุญาตให้เข้าถึงโหมดข้อมูลรับรองของคำขอที่เริ่มต้นโดย XMLHttpRequest ถูกควบคุมโดยแอตทริบิวต์ withCredentials "
mruanova

@mruanova คุณแน่ใจหรือไม่ว่าส่วนหัว Access-Control-Allow-Origin ถูกตั้งค่าอย่างถูกต้องในคำขอ ดูเหมือนว่ามีบางอย่างถูกส่งมาพร้อมกับสัญลักษณ์แทน
geekonaut

14

หากคุณใช้มิดเดิลแวร์ CORS และต้องการส่งwithCredentialsบูลีนจริงคุณสามารถกำหนดค่า CORS ได้ดังนี้:

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

`


3
คำตอบช่วยชีวิต +1 สำหรับสิ่งนั้น
Nisharg Shah

1
ฉันพยายามแก้ปัญหานี้มาตลอดทั้งวัน คุณคือผู้กอบกู้!
Hasan Sefa Ozalp

11

การปรับแต่ง CORS สำหรับ Angular 5 และ Spring Security (โซลูชันฐานคุกกี้)

ที่ด้านมุมจำเป็นต้องเพิ่มแฟล็กตัวเลือกwithCredentials: trueสำหรับการขนส่งคุกกี้:

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

ถ้ามันช่วยได้ฉันใช้เครื่องหมุนเหวี่ยงกับแอพ reactjs ของฉันและหลังจากตรวจสอบความคิดเห็นด้านล่างฉันดูไฟล์ไลบรารี centrifuge.js ซึ่งในเวอร์ชันของฉันมีข้อมูลโค้ดต่อไปนี้:

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

หลังจากที่ฉันลบทั้งสามบรรทัดนี้แอปก็ทำงานได้ดีตามที่คาดไว้

หวังว่าจะช่วยได้!


ขอบคุณ ... สิ่งนี้ช่วยฉันได้มาก! :)
pavan kumar chaitanya

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 () ภายในคลาสเริ่มต้นของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.