diff --git a/src/Nancy/Cookies/INancyCookie.cs b/src/Nancy/Cookies/INancyCookie.cs
index 31989b93cc..a36b50745f 100644
--- a/src/Nancy/Cookies/INancyCookie.cs
+++ b/src/Nancy/Cookies/INancyCookie.cs
@@ -52,5 +52,10 @@ public interface INancyCookie
/// Whether the cookie is secure (i.e. HTTPS only)
///
bool Secure { get; }
+
+ ///
+ /// Wheather the cookie is same site
+ ///
+ SameSite? SameSite { get; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Nancy/Cookies/NancyCookie.cs b/src/Nancy/Cookies/NancyCookie.cs
index 4e4ee00b8b..091b44a8b2 100644
--- a/src/Nancy/Cookies/NancyCookie.cs
+++ b/src/Nancy/Cookies/NancyCookie.cs
@@ -30,7 +30,7 @@ public NancyCookie(string name, string value)
/// The value of the cookie.
/// The expiration date of the cookie. Can be if it should expire at the end of the session.
public NancyCookie(string name, string value, DateTime expires)
- : this(name, value, false, false, expires)
+ : this(name, value, false, false, expires, null)
{
}
@@ -42,7 +42,7 @@ public NancyCookie(string name, string value, DateTime expires)
/// The value of the cookie.
/// Whether the cookie is http only.
public NancyCookie(string name, string value, bool httpOnly)
- : this(name, value, httpOnly, false, null)
+ : this(name, value, httpOnly, false, null, null)
{
}
@@ -55,7 +55,7 @@ public NancyCookie(string name, string value, bool httpOnly)
/// Whether the cookie is http only.
/// Whether the cookie is secure (i.e. HTTPS only).
public NancyCookie(string name, string value, bool httpOnly, bool secure)
- : this(name, value, httpOnly, secure, null)
+ : this(name, value, httpOnly, secure, null, null)
{
}
@@ -68,13 +68,15 @@ public NancyCookie(string name, string value, bool httpOnly, bool secure)
/// Whether the cookie is http only.
/// Whether the cookie is secure (i.e. HTTPS only).
/// The expiration date of the cookie. Can be if it should expire at the end of the session.
- public NancyCookie(string name, string value, bool httpOnly, bool secure, DateTime? expires)
+ /// The same site attribute of the cookie. Can be .
+ public NancyCookie(string name, string value, bool httpOnly, bool secure, DateTime? expires, SameSite? sameSite = null)
{
this.Name = name;
this.Value = value;
this.HttpOnly = httpOnly;
this.Secure = secure;
this.Expires = expires;
+ this.SameSite = sameSite;
}
///
@@ -135,6 +137,11 @@ public string EncodedValue
///
public bool Secure { get; private set; }
+ ///
+ /// Wheather the cookie is same site
+ ///
+ public SameSite? SameSite { get; set; }
+
///
/// Returns a that represents this instance.
///
@@ -169,7 +176,12 @@ public override string ToString()
sb.Append("; HttpOnly");
}
+ if(SameSite.HasValue)
+ {
+ sb.Append("; samesite=").Append(SameSite.ToString());
+ }
+
return sb.ToString();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Nancy/Cookies/SameSite.cs b/src/Nancy/Cookies/SameSite.cs
new file mode 100644
index 0000000000..9477dc40e5
--- /dev/null
+++ b/src/Nancy/Cookies/SameSite.cs
@@ -0,0 +1,29 @@
+namespace Nancy.Cookies
+{
+ ///
+ /// Represents the SameSite for NancyCookie
+ ///
+ public enum SameSite
+ {
+ ///
+ /// If the value is invalid, the cookie will only be sent along with
+ /// "same-site" requests. If the value is "Lax", the cookie will be
+ /// sent with "same-site" requests, and with "cross-site" top-level navigations
+ ///
+ Lax = 0,
+
+ ///
+ /// If you set SameSite to Strict, your cookie will only be sent in a
+ /// first-party context. In user terms, the cookie will only be sent
+ /// if the site for the cookie matches the site currently shown in
+ /// the browser's URL bar.
+ ///
+ Strict,
+
+ ///
+ /// Cookies with SameSite=None must also specify Secure,
+ /// meaning they require a secure context.
+ ///
+ None
+ }
+}
diff --git a/test/Nancy.Tests/Unit/NancyCookieFixture.cs b/test/Nancy.Tests/Unit/NancyCookieFixture.cs
index fb8ac9b93f..a916763f62 100644
--- a/test/Nancy.Tests/Unit/NancyCookieFixture.cs
+++ b/test/Nancy.Tests/Unit/NancyCookieFixture.cs
@@ -162,6 +162,16 @@ public void Should_encode_value_if_necessary()
result.ShouldEqual("Value+with+spaces");
}
+ [Fact]
+ public void Should_add_same_site_if_set()
+ {
+ // When
+ var cookie = new NancyCookie("leto", "worm") { SameSite = SameSite.Lax }.ToString();
+
+ // Then
+ cookie.ShouldEqual("leto=worm; path=/; samesite=Lax");
+ }
+
public static string GetInvariantAbbreviatedMonthName(DateTime dateTime)
{
return CultureInfo.InvariantCulture.DateTimeFormat.AbbreviatedMonthNames[dateTime.Month - 1];
@@ -173,4 +183,4 @@ public static string GetInvariantAbbreviatedWeekdayName(DateTime dateTime)
}
}
-}
\ No newline at end of file
+}