{"id":18494836,"url":"https://github.com/gbrlsnchs/jwt","last_synced_at":"2025-04-09T05:04:27.454Z","repository":{"id":39005303,"uuid":"120491515","full_name":"gbrlsnchs/jwt","owner":"gbrlsnchs","description":"Go JWT signing, verifying and validating","archived":false,"fork":false,"pushed_at":"2023-02-25T00:53:48.000Z","size":471,"stargazers_count":447,"open_issues_count":4,"forks_count":34,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-02T03:15:20.266Z","etag":null,"topics":["ecdsa-signature","ed25519","go","go-modules","golang","hmac","hmac-sha256","hmac-sha384","hmac-sha512","hmac-signature","jws","jwt","jwt-auth","jwt-authentication","jwt-token","rsa-signature","signing","verifying-signatures"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gbrlsnchs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":null,"patreon":"gbrlsnchs","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-02-06T16:51:42.000Z","updated_at":"2025-02-11T21:33:50.000Z","dependencies_parsed_at":"2024-06-18T12:31:00.627Z","dependency_job_id":"0607ae3a-00fd-4347-821d-df65c90f6163","html_url":"https://github.com/gbrlsnchs/jwt","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbrlsnchs%2Fjwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbrlsnchs%2Fjwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbrlsnchs%2Fjwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbrlsnchs%2Fjwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gbrlsnchs","download_url":"https://codeload.github.com/gbrlsnchs/jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980808,"owners_count":21027803,"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":["ecdsa-signature","ed25519","go","go-modules","golang","hmac","hmac-sha256","hmac-sha384","hmac-sha512","hmac-signature","jws","jwt","jwt-auth","jwt-authentication","jwt-token","rsa-signature","signing","verifying-signatures"],"created_at":"2024-11-06T13:22:24.202Z","updated_at":"2025-04-09T05:04:27.428Z","avatar_url":"https://github.com/gbrlsnchs.png","language":"Go","funding_links":["https://patreon.com/gbrlsnchs"],"categories":["Go"],"sub_categories":[],"readme":"# jwt (JSON Web Token for Go)\n[![JWT compatible](https://jwt.io/img/badge.svg)](https://jwt.io)  \n\n[![Github Actions Status](https://github.com/gbrlsnchs/jwt/workflows/Linux,%20macOS%20and%20Windows/badge.svg)](https://github.com/gbrlsnchs/jwt/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/gbrlsnchs/jwt)](https://goreportcard.com/report/github.com/gbrlsnchs/jwt)\n[![GoDoc](https://godoc.org/github.com/gbrlsnchs/jwt?status.svg)](https://pkg.go.dev/github.com/gbrlsnchs/jwt/v3)\n[![Version compatibility with Go 1.11 onward using modules](https://img.shields.io/badge/compatible%20with-go1.11+-5272b4.svg)](https://github.com/gbrlsnchs/jwt#installing)\n[![Join the chat at https://gitter.im/gbrlsnchs/jwt](https://badges.gitter.im/gbrlsnchs/jwt.svg)](https://gitter.im/gbrlsnchs/jwt?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n## About\nThis package is a JWT signer, verifier and validator for [Go](https://golang.org) (or Golang).\n\nAlthough there are many JWT packages out there for Go, many lack support for some signing, verifying or validation methods and, when they don't, they're overcomplicated. This package tries to mimic the ease of use from [Node JWT library](https://github.com/auth0/node-jsonwebtoken)'s API while following the [Effective Go](https://golang.org/doc/effective_go.html) guidelines.\n\nSupport for [JWE](https://tools.ietf.org/html/rfc7516) isn't provided (not yet but is in the roadmap, see #17). Instead, [JWS](https://tools.ietf.org/html/rfc7515) is used, narrowed down to the [JWT specification](https://tools.ietf.org/html/rfc7519).\n\n### Supported signing methods\n|         | SHA-256            | SHA-384            | SHA-512            |\n|:-------:|:------------------:|:------------------:|:------------------:|\n| HMAC    | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\n| RSA     | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\n| RSA-PSS | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\n| ECDSA   | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\n| EdDSA   | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_check_mark: |\n\n## Important\nBranch `master` is unstable, **always** use tagged versions. That way it is possible to differentiate pre-release tags from production ones.\nIn other words, API changes all the time in `master`. It's a place for public experiment. Thus, make use of the latest stable version via Go modules.\n\n## Usage\nFull documentation [here](https://pkg.go.dev/github.com/gbrlsnchs/jwt/v3).\n\n### Installing\n#### Important\nFor Go 1.11, make sure the environment variable `GO111MODULE` is set as `on` when running the install command.\n\n```sh\n$ go get -u github.com/gbrlsnchs/jwt/v3\n```\n\n### Signing\n```go\nimport (\n\t\"time\"\n\n\t\"github.com/gbrlsnchs/jwt/v3\"\n)\n\ntype CustomPayload struct {\n\tjwt.Payload\n\tFoo string `json:\"foo,omitempty\"`\n\tBar int    `json:\"bar,omitempty\"`\n}\n\nvar hs = jwt.NewHS256([]byte(\"secret\"))\n\nfunc main() {\n\tnow := time.Now()\n\tpl := CustomPayload{\n\t\tPayload: jwt.Payload{\n\t\t\tIssuer:         \"gbrlsnchs\",\n\t\t\tSubject:        \"someone\",\n\t\t\tAudience:       jwt.Audience{\"https://golang.org\", \"https://jwt.io\"},\n\t\t\tExpirationTime: jwt.NumericDate(now.Add(24 * 30 * 12 * time.Hour)),\n\t\t\tNotBefore:      jwt.NumericDate(now.Add(30 * time.Minute)),\n\t\t\tIssuedAt:       jwt.NumericDate(now),\n\t\t\tJWTID:          \"foobar\",\n\t\t},\n\t\tFoo: \"foo\",\n\t\tBar: 1337,\n\t}\n\n\ttoken, err := jwt.Sign(pl, hs)\n\tif err != nil {\n\t\t// ...\n\t}\n\n\t// ...\n}\n```\n\n### Verifying\n```go\nimport \"github.com/gbrlsnchs/jwt/v3\"\n\ntype CustomPayload struct {\n\tjwt.Payload\n\tFoo string `json:\"foo,omitempty\"`\n\tBar int    `json:\"bar,omitempty\"`\n}\n\nvar hs = jwt.NewHS256([]byte(\"secret\"))\n\nfunc main() {\n\t// ...\n\n\tvar pl CustomPayload\n\thd, err := jwt.Verify(token, hs, \u0026pl)\n\tif err != nil {\n\t\t// ...\n\t}\n\n\t// ...\n}\n```\n\n### Other use case examples\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eSetting \"cty\" and \"kid\" claims\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\nThe \"cty\" and \"kid\" claims can be set by passing options to the `jwt.Sign` function:\n```go\nimport (\n\t\"time\"\n\n\t\"github.com/gbrlsnchs/jwt/v3\"\n)\n\nvar hs = jwt.NewHS256([]byte(\"secret\"))\n\nfunc main() {\n\tpl := jwt.Payload{\n\t\tSubject:  \"gbrlsnchs\",\n\t\tIssuer:   \"gsr.dev\",\n\t\tIssuedAt: jwt.NumericDate(time.Now()),\n\t}\n\n\ttoken, err := jwt.Sign(pl, hs, jwt.ContentType(\"JWT\"), jwt.KeyID(\"my_key\"))\n\tif err != nil {\n\t\t// ...\n\t}\n\n\t// ...\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eValidating claims\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\n\n```go\nimport (\n\t\"time\"\n\n\t\"github.com/gbrlsnchs/jwt/v3\"\n)\n\ntype CustomPayload struct {\n\tjwt.Payload\n\tFoo string `json:\"foo,omitempty\"`\n\tBar int    `json:\"bar,omitempty\"`\n}\n\nvar hs = jwt.NewHS256([]byte(\"secret\"))\n\nfunc main() {\n\t// ...\n\n\tvar (\n\t\tnow = time.Now()\n\t\taud = jwt.Audience{\"https://golang.org\"}\n\n\t\t// Validate claims \"iat\", \"exp\" and \"aud\".\n\t\tiatValidator = jwt.IssuedAtValidator(now)\n\t\texpValidator = jwt.ExpirationTimeValidator(now)\n\t\taudValidator = jwt.AudienceValidator(aud)\n\n\t\t// Use jwt.ValidatePayload to build a jwt.VerifyOption.\n\t\t// Validators are run in the order informed.\n\t\tpl              CustomPayload\n\t\tvalidatePayload = jwt.ValidatePayload(\u0026pl.Payload, iatValidator, expValidator, audValidator)\n\t)\n\n\thd, err := jwt.Verify(token, hs, \u0026pl, validatePayload)\n\tif err != nil {\n\t\t// ...\n\t}\n\n\t// ...\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eValidating \"alg\" before verifying\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\nFor validating the \"alg\" field in a JOSE header **before** verification, the `jwt.ValidateHeader` option must be passed to `jwt.Verify`.\n```go\nimport \"github.com/gbrlsnchs/jwt/v3\"\n\nvar hs = jwt.NewHS256([]byte(\"secret\"))\n\nfunc main() {\n\t// ...\n\n\tvar pl jwt.Payload\n\tif _, err := jwt.Verify(token, hs, \u0026pl, jwt.ValidateHeader); err != nil {\n\t\t// ...\n\t}\n\n\t// ...\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eUsing an \u003ccode\u003eAlgorithm\u003c/code\u003e resolver\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\n```go\nimport (\n\t\"errors\"\n\n\t\"github.com/gbrlsnchs/jwt/v3\"\n\t\"github.com/gbrlsnchs/jwt/v3/jwtutil\"\n)\n\nvar (\n\t// ...\n\n\trs256 = jwt.NewRS256(jwt.RSAPublicKey(myRSAPublicKey))\n\tes256 = jwt.NewES256(jwt.ECDSAPublicKey(myECDSAPublicKey))\n)\n\nfunc main() {\n\trv := \u0026jwtutil.Resolver{New: func(hd jwt.Header) (jwt.Algorithm, error) {\n\t\tswitch hd.KeyID {\n\t\tcase \"foo\":\n\t\t\treturn rs256, nil\n\t\tcase \"bar\":\n\t\t\treturn es256, nil\n\t\tdefault:\n\t\t\treturn nil, errors.New(`invalid \"kid\"`)\n\t\t}\n\t}}\n\tvar pl jwt.Payload\n\tif _, err := jwt.Verify(token, rv, \u0026pl); err != nil {\n\t\t// ...\n\t}\n\n\t// ...\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n## Contributing\n### How to help\n- For bugs and opinions, please [open an issue](https://github.com/gbrlsnchs/jwt/issues/new)\n- For pushing changes, please [open a pull request](https://github.com/gbrlsnchs/jwt/compare)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbrlsnchs%2Fjwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgbrlsnchs%2Fjwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbrlsnchs%2Fjwt/lists"}