aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorTom <33637037+tflyons@users.noreply.github.com>2019-10-28 07:23:04 +0300
committerMatt Silverlock <matt@eatsleeprepeat.net>2019-10-28 07:23:04 +0300
commit61b4ad17eb88d0d1118560d1101176279be2bc88 (patch)
tree63a082a2de25c15b5705afbd0dc0320e3a2ceada /README.md
parent86450627d8e6b88e00ea41f228489b89d08a40de (diff)
docs: Include an example for using DecodeMulti in the Readme (#69)
* Include an example for using DecodeMulti in the Readme * Put warning in as code comment
Diffstat (limited to 'README.md')
-rw-r--r--README.md58
1 files changed, 58 insertions, 0 deletions
diff --git a/README.md b/README.md
index a914d4a..f416daa 100644
--- a/README.md
+++ b/README.md
@@ -77,6 +77,64 @@ registered first using gob.Register(). For basic types this is not needed;
it works out of the box. An optional JSON encoder that uses `encoding/json` is
available for types compatible with JSON.
+### Key Rotation
+Rotating keys is an important part of any security strategy. The `EncodeMulti` and
+`DecodeMulti` functions allow for multiple keys to be rotated in and out.
+For example, let's take a system that stores keys in a map:
+
+```go
+// keys stored in a map will not be persisted between restarts
+// a more persistent storage should be considered for production applications.
+var cookies = map[string]*securecookie.SecureCookie{
+ "previous": securecookie.New(
+ securecookie.GenerateRandomKey(64),
+ securecookie.GenerateRandomKey(32),
+ ),
+ "current": securecookie.New(
+ securecookie.GenerateRandomKey(64),
+ securecookie.GenerateRandomKey(32),
+ ),
+}
+```
+
+Using the current key to encode new cookies:
+```go
+func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
+ value := map[string]string{
+ "foo": "bar",
+ }
+ if encoded, err := securecookie.EncodeMulti("cookie-name", value, cookies["current"]); err == nil {
+ cookie := &http.Cookie{
+ Name: "cookie-name",
+ Value: encoded,
+ Path: "/",
+ }
+ http.SetCookie(w, cookie)
+ }
+}
+```
+
+Later, decode cookies. Check against all valid keys:
+```go
+func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
+ if cookie, err := r.Cookie("cookie-name"); err == nil {
+ value := make(map[string]string)
+ err = securecookie.DecodeMulti("cookie-name", cookie.Value, &value, cookies["current"], cookies["previous"])
+ if err == nil {
+ fmt.Fprintf(w, "The value of foo is %q", value["foo"])
+ }
+ }
+}
+```
+
+Rotate the keys. This strategy allows previously issued cookies to be valid until the next rotation:
+```go
+func Rotate(newCookie *securecookie.SecureCookie) {
+ cookies["previous"] = cookies["current"]
+ cookies["current"] = newCookie
+}
+```
+
## License
BSD licensed. See the LICENSE file for details.