ASP.NET Core 3.1 Razor Pages SameSite cookie 示例ASP.NET Core 3.1 Razor Pages SameSite cookie sample
本文内容
ASP.NET Core 3.0 内置了对SameSite属性的支持,包括 SameSiteMode
属性值 Unspecified
以禁止写入特性。
编写 SameSite 属性Writing the SameSite attribute
下面是如何在 cookie 上编写 SameSite 属性的示例;
var cookieOptions = new CookieOptions
{
// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS
Secure = true,
// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
HttpOnly = true,
// Add the SameSite attribute, this will emit the attribute with a value of none.
// To not emit the attribute at all set the SameSite property to SameSiteMode.Unspecified.
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append(CookieName, "cookieValue", cookieOptions);
设置 Cookie 身份验证和会话状态 cookieSetting Cookie Authentication and Session State cookies
Cookie 身份验证、会话状态和各种其他组件通过 Cookie 选项设置其 sameSite 选项,例如
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.IsEssential = true;
});
services.AddSession(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.IsEssential = true;
});
在上面显示的代码中,cookie 身份验证和会话状态将其 sameSite 属性设置为 None,使用 None
值发出属性,同时将 Secure 特性设置为 true。
运行示例Run the sample
如果运行示例项目,请在初始页面上加载浏览器调试器,并使用它查看站点的 cookie 集合。若要在 Edge 和 Chrome 中进行此操作,请按 F12
选择 "Application
" 选项卡,然后单击 "Storage
" 部分中 "Cookies
" 选项下的 "站点 URL"。
您可以从上图中看到,当您单击 "创建 SameSite Cookie" 按钮的 SameSite 属性值为 Lax
,与在示例代码中设置的值匹配时,示例创建的 cookie 就会看到该示例创建的 cookie。
截获 cookieIntercepting cookies
为了截获 cookie,若要根据用户的浏览器代理中的支持来调整无值,必须使用 CookiePolicy
中间件。这必须放入 http 请求管道中,然后才能在 ConfigureServices()
中写入 cookie 和配置的任何组件。
若要将其插入管道中,请使用Startup.cs的 Configure(IApplicationBuilder, IHostingEnvironment)
方法中的 app.UseCookiePolicy()
。例如:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
然后,在 ConfigureServices(IServiceCollection services)
配置 cookie 策略,以在附加或删除 cookie 时调用帮助器类,如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
Helper 函数 CheckSameSite(HttpContext, CookieOptions)
:
- 当 cookie 追加到请求或从请求中删除时调用。
- 检查
SameSite
属性是否设置为None
。 - 如果
SameSite
设置为None
并且已知当前用户代理不支持 none 特性值。使用SameSiteSupport类完成检查:- 通过将属性设置为,将
SameSite
设置为不发出该值(SameSiteMode)(-1)
- 通过将属性设置为,将