{"id":13676632,"url":"https://github.com/gorilla/securecookie","last_synced_at":"2025-04-29T07:32:51.614Z","repository":{"id":4896195,"uuid":"6051826","full_name":"gorilla/securecookie","owner":"gorilla","description":"Package gorilla/securecookie encodes and decodes authenticated and optionally encrypted cookie values for Go web applications.","archived":false,"fork":false,"pushed_at":"2023-11-08T15:56:24.000Z","size":129,"stargazers_count":708,"open_issues_count":6,"forks_count":147,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-04-22T10:25:13.841Z","etag":null,"topics":["cookie","cookies","go","golang","gorilla","gorilla-web-toolkit","securecookie","sessions"],"latest_commit_sha":null,"homepage":"https://gorilla.github.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"rhysbrettbowen/PlastronJS","license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gorilla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-10-02T21:33:33.000Z","updated_at":"2025-04-13T10:02:28.000Z","dependencies_parsed_at":"2023-01-13T13:17:10.955Z","dependency_job_id":"84f1b8fa-be49-442c-a5e7-5a82664f9c41","html_url":"https://github.com/gorilla/securecookie","commit_stats":{"total_commits":63,"total_committers":22,"mean_commits":"2.8636363636363638","dds":0.7301587301587302,"last_synced_commit":"eae3c1840ec4adda88a4af683ad0f60bb690e7c2"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gorilla%2Fsecurecookie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gorilla%2Fsecurecookie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gorilla%2Fsecurecookie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gorilla%2Fsecurecookie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gorilla","download_url":"https://codeload.github.com/gorilla/securecookie/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251456053,"owners_count":21592285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cookie","cookies","go","golang","gorilla","gorilla-web-toolkit","securecookie","sessions"],"created_at":"2024-08-02T13:00:30.694Z","updated_at":"2025-04-29T07:32:47.739Z","avatar_url":"https://github.com/gorilla.png","language":"Go","funding_links":[],"categories":["开源类库","Middlewares \u0026 framework add-ons","Open source library","Go","Web Framework Hardening"],"sub_categories":["Auth"],"readme":"# gorilla/securecookie\n\n![testing](https://github.com/gorilla/securecookie/actions/workflows/test.yml/badge.svg)\n[![codecov](https://codecov.io/github/gorilla/securecookie/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/securecookie)\n[![godoc](https://godoc.org/github.com/gorilla/securecookie?status.svg)](https://godoc.org/github.com/gorilla/securecookie)\n[![sourcegraph](https://sourcegraph.com/github.com/gorilla/securecookie/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/securecookie?badge)\n\n![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)\n\nsecurecookie encodes and decodes authenticated and optionally encrypted\ncookie values.\n\nSecure cookies can't be forged, because their values are validated using HMAC.\nWhen encrypted, the content is also inaccessible to malicious eyes. It is still\nrecommended that sensitive data not be stored in cookies, and that HTTPS be used\nto prevent cookie [replay attacks](https://en.wikipedia.org/wiki/Replay_attack).\n\n## Examples\n\nTo use it, first create a new SecureCookie instance:\n\n```go\n// Hash keys should be at least 32 bytes long\nvar hashKey = []byte(\"very-secret\")\n// Block keys should be 16 bytes (AES-128) or 32 bytes (AES-256) long.\n// Shorter keys may weaken the encryption used.\nvar blockKey = []byte(\"a-lot-secret\")\nvar s = securecookie.New(hashKey, blockKey)\n```\n\nThe hashKey is required, used to authenticate the cookie value using HMAC.\nIt is recommended to use a key with 32 or 64 bytes.\n\nThe blockKey is optional, used to encrypt the cookie value -- set it to nil\nto not use encryption. If set, the length must correspond to the block size\nof the encryption algorithm. For AES, used by default, valid lengths are\n16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.\n\nStrong keys can be created using the convenience function\n`GenerateRandomKey()`. Note that keys created using `GenerateRandomKey()` are not\nautomatically persisted. New keys will be created when the application is\nrestarted, and previously issued cookies will not be able to be decoded.\n\nOnce a SecureCookie instance is set, use it to encode a cookie value:\n\n```go\nfunc SetCookieHandler(w http.ResponseWriter, r *http.Request) {\n\tvalue := map[string]string{\n\t\t\"foo\": \"bar\",\n\t}\n\tif encoded, err := s.Encode(\"cookie-name\", value); err == nil {\n\t\tcookie := \u0026http.Cookie{\n\t\t\tName:  \"cookie-name\",\n\t\t\tValue: encoded,\n\t\t\tPath:  \"/\",\n\t\t\tSecure: true,\n\t\t\tHttpOnly: true,\n\t\t}\n\t\thttp.SetCookie(w, cookie)\n\t}\n}\n```\n\nLater, use the same SecureCookie instance to decode and validate a cookie\nvalue:\n\n```go\nfunc ReadCookieHandler(w http.ResponseWriter, r *http.Request) {\n\tif cookie, err := r.Cookie(\"cookie-name\"); err == nil {\n\t\tvalue := make(map[string]string)\n\t\tif err = s2.Decode(\"cookie-name\", cookie.Value, \u0026value); err == nil {\n\t\t\tfmt.Fprintf(w, \"The value of foo is %q\", value[\"foo\"])\n\t\t}\n\t}\n}\n```\n\nWe stored a map[string]string, but secure cookies can hold any value that\ncan be encoded using `encoding/gob`. To store custom types, they must be\nregistered first using gob.Register(). For basic types this is not needed;\nit works out of the box. An optional JSON encoder that uses `encoding/json` is\navailable for types compatible with JSON.\n\n### Key Rotation\nRotating keys is an important part of any security strategy. The `EncodeMulti` and\n`DecodeMulti` functions allow for multiple keys to be rotated in and out.\nFor example, let's take a system that stores keys in a map:\n\n```go\n// keys stored in a map will not be persisted between restarts\n// a more persistent storage should be considered for production applications.\nvar cookies = map[string]*securecookie.SecureCookie{\n\t\"previous\": securecookie.New(\n\t\tsecurecookie.GenerateRandomKey(64),\n\t\tsecurecookie.GenerateRandomKey(32),\n\t),\n\t\"current\": securecookie.New(\n\t\tsecurecookie.GenerateRandomKey(64),\n\t\tsecurecookie.GenerateRandomKey(32),\n\t),\n}\n```\n\nUsing the current key to encode new cookies:\n```go\nfunc SetCookieHandler(w http.ResponseWriter, r *http.Request) {\n\tvalue := map[string]string{\n\t\t\"foo\": \"bar\",\n\t}\n\tif encoded, err := securecookie.EncodeMulti(\"cookie-name\", value, cookies[\"current\"]); err == nil {\n\t\tcookie := \u0026http.Cookie{\n\t\t\tName:  \"cookie-name\",\n\t\t\tValue: encoded,\n\t\t\tPath:  \"/\",\n\t\t}\n\t\thttp.SetCookie(w, cookie)\n\t}\n}\n```\n\nLater, decode cookies. Check against all valid keys:\n```go\nfunc ReadCookieHandler(w http.ResponseWriter, r *http.Request) {\n\tif cookie, err := r.Cookie(\"cookie-name\"); err == nil {\n\t\tvalue := make(map[string]string)\n\t\terr = securecookie.DecodeMulti(\"cookie-name\", cookie.Value, \u0026value, cookies[\"current\"], cookies[\"previous\"])\n\t\tif err == nil {\n\t\t\tfmt.Fprintf(w, \"The value of foo is %q\", value[\"foo\"])\n\t\t}\n\t}\n}\n```\n\nRotate the keys. This strategy allows previously issued cookies to be valid until the next rotation:\n```go\nfunc Rotate(newCookie *securecookie.SecureCookie) {\n\tcookies[\"previous\"] = cookies[\"current\"]\n\tcookies[\"current\"] = newCookie\n}\n```\n\n## License\n\nBSD licensed. See the LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgorilla%2Fsecurecookie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgorilla%2Fsecurecookie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgorilla%2Fsecurecookie/lists"}