{"id":16216272,"url":"https://github.com/matthewhartstonge/pkce","last_synced_at":"2025-04-07T22:43:20.692Z","repository":{"id":57652826,"uuid":"451412947","full_name":"matthewhartstonge/pkce","owner":"matthewhartstonge","description":"A specification compliant implementation of RFC7636 - \"Proof Key for Code Exchange (PKCE)\" for Go.","archived":false,"fork":false,"pushed_at":"2022-01-26T22:34:50.000Z","size":48,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-14T00:16:54.985Z","etag":null,"topics":["code-flow-pkce","go","go-module","golang","oauth2","oidc","pkce"],"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/matthewhartstonge.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-24T10:13:30.000Z","updated_at":"2024-03-19T12:44:50.000Z","dependencies_parsed_at":"2022-08-25T20:21:08.684Z","dependency_job_id":null,"html_url":"https://github.com/matthewhartstonge/pkce","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewhartstonge%2Fpkce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewhartstonge%2Fpkce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewhartstonge%2Fpkce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewhartstonge%2Fpkce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthewhartstonge","download_url":"https://codeload.github.com/matthewhartstonge/pkce/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247744283,"owners_count":20988781,"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":["code-flow-pkce","go","go-module","golang","oauth2","oidc","pkce"],"created_at":"2024-10-10T11:18:55.765Z","updated_at":"2025-04-07T22:43:20.672Z","avatar_url":"https://github.com/matthewhartstonge.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pkce\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/matthewhartstonge/pkce.svg)](https://pkg.go.dev/github.com/matthewhartstonge/pkce)\n[![Go Report Card](https://goreportcard.com/badge/github.com/matthewhartstonge/pkce)](https://goreportcard.com/report/github.com/matthewhartstonge/pkce)\n[![Build](https://github.com/matthewhartstonge/pkce/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/matthewhartstonge/pkce/actions/workflows/build.yml)\n\n`pkce` implements the client side of RFC 7636 \"Proof Key for Code Exchange by OAuth Public Clients\" (PKCE) to enable the\ngeneration of cryptographically secure and specification compliant code verifiers and code challenges. With :sparkles:\nno external dependencies :sparkles:.\n\n## Getting Started\n\n`pkce` makes use of go mod, you can install it by using go get:\n\n```shell\ngo get github.com/matthewhartstonge/pkce\n```\n\n## Examples\n\n### Structs\n\nFor those that like abstractions, feel free to enjoy \"safety:tm:\":\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/matthewhartstonge/pkce\"\n)\n\nfunc main() {\n\t// Generate a secure proof key! \n\t// Make sure yo do this each time you want a new proof key - it's stateful.\n\tkey, err := pkce.New()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(\"my generated code verifier is:\", key.CodeVerifier())\n\tfmt.Println(\"my generated plain code challenge is:\", key.CodeChallenge())\n\n\t// Finally - on the server-side side, we can verify the received code \n\t// verifier:\n\treceivedCodeVerifier := \"#yolo-cant-verify-me-mr-mcbaggins\"\n\tisValid := key.VerifyCodeVerifier(receivedCodeVerifier)\n\tfmt.Println(\"is the received code verifier valid?\", isValid)\n}\n```\n\nOkay, so that was a bit easy... But, what can I configure?!?\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/matthewhartstonge/pkce\"\n)\n\nfunc main() {\n\t// Generate a ... proof key!\n\tkey, err := pkce.New(\n\t\t// pkce.WithCodeVerifierLength enables increasing entropy for \n\t\t// super-duper securities!\n\t\tpkce.WithCodeVerifierLength(9001),\n\n\t\t// pkce.WithChallengeMethod enables setting the PKCE mode, which is \n\t\t// really code name for setting the method to \"plain\" for, you know, if\n\t\t// you've got a non-compliant OAuth PKCE accepting server that may \n\t\t// require backwards compatibility. #SnarkIntended\n\t\tpkce.WithChallengeMethod(pkce.Plain),\n\n\t\t// pkce.WithCodeVerifier enables BYO code verifier.\n\t\t//\n\t\t// ... I hope you use a secure implementation ...\n\t\t//\n\t\t// This is mainly useful if you like the struct style of encapsulation, \n\t\t// or if loading the verifier from a datastore.\n\t\t//\n\t\t// Using this option will disable code verifier generation, therefore \n\t\t// `pkce.WithCodeVerifierLength` will be redundant if specified.\n\t\tpkce.WithCodeVerifier([]byte(\"#YOLO\")),\n\t)\n\tif err != nil {\n\t\t// hah, yeah, there's gonna be an error or two...\n\t\tpanic(err)\n\t}\n\n\t// ... otherwise, it's business as usual ...\n```\n\n### Functional\n\nFor those that like functions, you can fight against your own \"to err == programmer\"\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/matthewhartstonge/pkce\"\n)\n\nfunc main() {\n\t// Generate a secure code verifier!\n\tcodeVerifier, err := pkce.GenerateCodeVerifier(50)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// OR, lawd forbid, you can generate and send in your own code verifier...\n\t//    ... don't do this ...\n\n\t// Then we can generate a code challenge based on the incoming code \n\t// challenge method\n\tcodeChallenge, err := pkce.GenerateCodeChallenge(pkce.S256, codeVerifier)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(\"my manually generated code verifier is:\", codeVerifier)\n\tfmt.Println(\"my manually generated code challenge is:\", codeChallenge)\n\n\t// Finally - on the server-side side, we can verify the received code \n\t// verifier:\n\tincomingCodeVerifier := \"#yolo-cant-verify-me-mr-mcbaggins\"\n\tisValid := pkce.VerifyCodeVerifier(pkce.S256, incomingCodeVerifier, codeChallenge)\n\tfmt.Println(\"is the received code verifier valid?\", isValid)\n}\n\n```\n\n## What is PKCE?\n\nGreat Question!\n\nFor more information on \"Proof Key for Code Exchange (PKCE) by OAuth Public Clients\" (or for some light bedtime reading)\ncheck out the following links:\n\n* [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)\n* [Auth0 - How PKCE Works](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-proof-key-for-code-exchange-pkce#how-it-works)\n* [OAuth - \"Protecting Apps with PKCE\"](https://www.oauth.com/oauth2-servers/pkce/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewhartstonge%2Fpkce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatthewhartstonge%2Fpkce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewhartstonge%2Fpkce/lists"}