mirror of https://github.com/gofiber/fiber.git
✨ v3 (feature): add CHIPS support to Cookie (#3047)
* ✨ v3 (feature): add CHIPS support to Cookie
* update docs
* Update docs/whats_new.md
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update docs/api/ctx.md
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
pull/3055/head
parent
a18e8a8967
commit
56d60a084e
25
ctx.go
25
ctx.go
|
@ -175,16 +175,17 @@ type RangeSet struct {
|
||||||
|
|
||||||
// Cookie data for c.Cookie
|
// Cookie data for c.Cookie
|
||||||
type Cookie struct {
|
type Cookie struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"` // The name of the cookie
|
||||||
Value string `json:"value"`
|
Value string `json:"value"` // The value of the cookie
|
||||||
Path string `json:"path"`
|
Path string `json:"path"` // Specifies a URL path which is allowed to receive the cookie
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"` // Specifies the domain which is allowed to receive the cookie
|
||||||
MaxAge int `json:"max_age"`
|
MaxAge int `json:"max_age"` // The maximum age (in seconds) of the cookie
|
||||||
Expires time.Time `json:"expires"`
|
Expires time.Time `json:"expires"` // The expiration date of the cookie
|
||||||
Secure bool `json:"secure"`
|
Secure bool `json:"secure"` // Indicates that the cookie should only be transmitted over a secure HTTPS connection
|
||||||
HTTPOnly bool `json:"http_only"`
|
HTTPOnly bool `json:"http_only"` // Indicates that the cookie is accessible only through the HTTP protocol
|
||||||
SameSite string `json:"same_site"`
|
SameSite string `json:"same_site"` // Controls whether or not a cookie is sent with cross-site requests
|
||||||
SessionOnly bool `json:"session_only"`
|
Partitioned bool `json:"partitioned"` // Indicates if the cookie is stored in a partitioned cookie jar
|
||||||
|
SessionOnly bool `json:"session_only"` // Indicates if the cookie is a session-only cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
// Views is the interface that wraps the Render function.
|
// Views is the interface that wraps the Render function.
|
||||||
|
@ -437,6 +438,10 @@ func (c *DefaultCtx) Cookie(cookie *Cookie) {
|
||||||
fcookie.SetSameSite(fasthttp.CookieSameSiteLaxMode)
|
fcookie.SetSameSite(fasthttp.CookieSameSiteLaxMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHIPS allows to partition cookie jar by top-level site.
|
||||||
|
// refer: https://developers.google.com/privacy-sandbox/3pcd/chips
|
||||||
|
fcookie.SetPartitioned(cookie.Partitioned)
|
||||||
|
|
||||||
c.fasthttp.Response.Header.SetCookie(fcookie)
|
c.fasthttp.Response.Header.SetCookie(fcookie)
|
||||||
fasthttp.ReleaseCookie(fcookie)
|
fasthttp.ReleaseCookie(fcookie)
|
||||||
}
|
}
|
||||||
|
|
|
@ -920,6 +920,11 @@ func Test_Ctx_Cookie(t *testing.T) {
|
||||||
cookie.MaxAge = 0
|
cookie.MaxAge = 0
|
||||||
c.Cookie(cookie)
|
c.Cookie(cookie)
|
||||||
require.Equal(t, expect, string(c.Response().Header.Peek(HeaderSetCookie)))
|
require.Equal(t, expect, string(c.Response().Header.Peek(HeaderSetCookie)))
|
||||||
|
|
||||||
|
expect = "username=john; path=/; secure; SameSite=None; Partitioned"
|
||||||
|
cookie.Partitioned = true
|
||||||
|
c.Cookie(cookie)
|
||||||
|
require.Equal(t, expect, string(c.Response().Header.Peek(HeaderSetCookie)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// go test -v -run=^$ -bench=Benchmark_Ctx_Cookie -benchmem -count=4
|
// go test -v -run=^$ -bench=Benchmark_Ctx_Cookie -benchmem -count=4
|
||||||
|
|
|
@ -375,16 +375,17 @@ func (c Ctx) Cookie(cookie *Cookie)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Cookie struct {
|
type Cookie struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"` // The name of the cookie
|
||||||
Value string `json:"value"`
|
Value string `json:"value"` // The value of the cookie
|
||||||
Path string `json:"path"`
|
Path string `json:"path"` // Specifies a URL path which is allowed to receive the cookie
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"` // Specifies the domain which is allowed to receive the cookie
|
||||||
MaxAge int `json:"max_age"`
|
MaxAge int `json:"max_age"` // The maximum age (in seconds) of the cookie
|
||||||
Expires time.Time `json:"expires"`
|
Expires time.Time `json:"expires"` // The expiration date of the cookie
|
||||||
Secure bool `json:"secure"`
|
Secure bool `json:"secure"` // Indicates that the cookie should only be transmitted over a secure HTTPS connection
|
||||||
HTTPOnly bool `json:"http_only"`
|
HTTPOnly bool `json:"http_only"` // Indicates that the cookie is accessible only through the HTTP protocol
|
||||||
SameSite string `json:"same_site"`
|
SameSite string `json:"same_site"` // Controls whether or not a cookie is sent with cross-site requests
|
||||||
SessionOnly bool `json:"session_only"`
|
Partitioned bool `json:"partitioned"` // Indicates if the cookie is stored in a partitioned cookie jar
|
||||||
|
SessionOnly bool `json:"session_only"` // Indicates if the cookie is a session-only cookie
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -402,6 +403,26 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::info
|
||||||
|
|
||||||
|
Partitioned cookies allow partitioning the cookie jar by top-level site, enhancing user privacy by preventing cookies from being shared across different sites. This feature is particularly useful in scenarios where a user interacts with embedded third-party services that should not have access to the main site's cookies. You can check out [CHIPS](https://developers.google.com/privacy-sandbox/3pcd/chips) for more information.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
```go title="Example"
|
||||||
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
// Create a new partitioned cookie
|
||||||
|
cookie := new(fiber.Cookie)
|
||||||
|
cookie.Name = "user_session"
|
||||||
|
cookie.Value = "abc123"
|
||||||
|
cookie.Partitioned = true // This cookie will be stored in a separate jar when it's embeded into another website
|
||||||
|
|
||||||
|
// Set the cookie in the response
|
||||||
|
c.Cookie(cookie)
|
||||||
|
return c.SendString("Partitioned cookie set")
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
## Cookies
|
## Cookies
|
||||||
|
|
||||||
Get cookie value by key, you could pass an optional default value that will be returned if the cookie key does not exist.
|
Get cookie value by key, you could pass an optional default value that will be returned if the cookie key does not exist.
|
||||||
|
|
|
@ -186,6 +186,9 @@ To enable the routing changes above we had to slightly adjust the signature of t
|
||||||
DRAFT section
|
DRAFT section
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- Cookie now allows Partitioned cookies for [CHIPS](https://developers.google.com/privacy-sandbox/3pcd/chips) support. CHIPS (Cookies Having Independent Partitioned State) is a feature that improves privacy by allowing cookies to be partitioned by top-level site, mitigating cross-site tracking.
|
||||||
|
|
||||||
### new methods
|
### new methods
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue