ASP.NET Core Web API 跨域(CORS) Cookie問題
- 2019 年 10 月 3 日
- 筆記
身為一個Web API,處理來自跨域不同源的請求,是一件十分合理的事情。
先上已有的文章,快速複製粘貼,啟用CORS:
Microsoft:啟用 ASP.NET Core 中的跨域請求 (CORS)
如果按照以上文章,一步一步操作,你會發現,雖然能跨域請求了,但是即使客戶端開了(xhr.withCredentials = true)也無法將Cookie發送給API。
關於AllowAnyOrigin
這是因為請求的首部中攜帶了 Cookie 資訊,如果 Access-Control-Allow-Origin 的值為「*」,請求將會失敗。而將 Access-Control-Allow-Origin 的值設置為 http://foo.example,則請求將成功執行。
PS: 雖然API用Cookie不是很合理,但有時舊介面改造升級卻不得不瞎搞,呵呵。
為什麼?
先看遍原理:
在來篇詳細的:
進一步了解:
紫雲飛: SameSite Cookie,防止 CSRF 攻擊
跳過簡單請求和預檢請求不談(不代表不重要),我們會發現一個叫SameSite的東西,是它告訴瀏覽器不要將Cookie發給非同源的Web API的,默認情況下,ASP.NET Core Web API 是啟用的。所以配置下關閉即可。
...... services.AddCors(options => { options.AddPolicy("any", policyBuilder => { policyBuilder.AllowAnyMethod() .AllowAnyHeader() //.WithMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "DEBUG"); .AllowCredentials();//指定處理cookie var cfg = Configuration.GetSection("AllowedHosts").Get<List<string>>(); if (cfg == null || cfg.Contains("*")) policyBuilder.AllowAnyOrigin(); //允許任何來源的主機訪問 else policyBuilder.WithOrigins(cfg.ToArray()); //允許類似http://localhost:8080等主機訪問 }); }); services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); ..... app.UseCors("any"); app.UseCookiePolicy();
或
..... services.AddCors(options => { options.AddPolicy("any", policyBuilder => { policyBuilder.AllowAnyMethod() .AllowAnyHeader() //.WithMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "DEBUG"); .AllowCredentials();//指定處理cookie var cfg = Configuration.GetSection("AllowedHosts").Get<List<string>>(); if (cfg == null || cfg.Contains("*")) policyBuilder.AllowAnyOrigin(); //允許任何來源的主機訪問 else policyBuilder.WithOrigins(cfg.ToArray()); //允許類似http://localhost:8080等主機訪問 }); }); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(configureOptions => { configureOptions.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; }); ...... app.UseCors("any"); app.UseAuthentication();
參考
https://docs.microsoft.com/zh-cn/aspnet/core/security/cors
http://www.ruanyifeng.com/blog/2016/04/cors.html
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
https://www.cnblogs.com/ziyunfei/p/5637945.html
聲明
本文採用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議進行許可,發表在CSDN和部落格園,歡迎讀者轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接!請讀者/爬蟲們尊重版權