{"action":"created","comment":{"url":"https://api.github.com/repos/go-kit/kit/pulls/comments/76119830","id":76119830,"diff_hunk":"@@ -0,0 +1,83 @@\n+package jwt\n+\n+import (\n+\t\"fmt\"\n+\tstdhttp \"net/http\"\n+\t\"strings\"\n+\n+\t\"github.com/go-kit/kit/transport/grpc\"\n+\t\"github.com/go-kit/kit/transport/http\"\n+\t\"golang.org/x/net/context\"\n+\t\"google.golang.org/grpc/metadata\"\n+)\n+\n+// moves JWT token from request header to context\n+// particularly useful for servers\n+func ToHTTPContext() http.RequestFunc {\n+\treturn func(ctx context.Context, r *stdhttp.Request) context.Context {\n+\t\ttoken, ok := extractTokenFromAuthHeader(r.Header.Get(\"Authorization\"))\n+\t\tif !ok {\n+\t\t\treturn ctx\n+\t\t}\n+\n+\t\treturn context.WithValue(ctx, JWTTokenContextKey, token)\n+\t}\n+}\n+\n+// moves JWT token from context to request header\n+// particularly useful for clients\n+func FromHTTPContext() http.RequestFunc {\n+\treturn func(ctx context.Context, r *stdhttp.Request) context.Context {\n+\t\ttoken, ok := ctx.Value(JWTTokenContextKey).(string)\n+\t\tif ok {\n+\t\t\tr.Header.Add(\"Authorization\", generateAuthHeaderFromToken(token))\n+\t\t}\n+\t\treturn ctx\n+\t}\n+}\n+\n+// moves JWT token from grpc metadata to context\n+// particularly userful for servers\n+func ToGRPCContext() grpc.RequestFunc {\n+\treturn func(ctx context.Context, md *metadata.MD) context.Context {\n+\t\t// capital \"Key\" is illegal in HTTP/2.\n+\t\tauthHeader, ok := (*md)[\"authorization\"]\n+\t\tif !ok {\n+\t\t\treturn ctx\n+\t\t}\n+\n+\t\ttoken, ok := extractTokenFromAuthHeader(authHeader[0])\n+\t\tif ok {\n+\t\t\tctx = context.WithValue(ctx, JWTTokenContextKey, token)\n+\t\t}\n+\n+\t\treturn ctx\n+\t}\n+}\n+\n+// moves JWT token from context to grpc metadata\n+// particularly useful for clients\n+func FromGRPCContext() grpc.RequestFunc {\n+\treturn func(ctx context.Context, md *metadata.MD) context.Context {\n+\t\ttoken, ok := ctx.Value(JWTTokenContextKey).(string)\n+\t\tif ok {\n+\t\t\t// capital \"Key\" is illegal in HTTP/2.\n+\t\t\t(*md)[\"authorization\"] = []string{generateAuthHeaderFromToken(token)}\n+\t\t}\n+\n+\t\treturn ctx\n+\t}\n+}\n+\n+// extractTokenFromAuthHeader returns the token from the value of the Authorzation header\n+func extractTokenFromAuthHeader(val string) (token string, ok bool) {\n+\tif len(val) < 8 || !strings.EqualFold(val[0:7], \"BEARER \") {","path":"auth/jwt/transport.go","position":74,"original_position":74,"commit_id":"fcaf088de953bcc2a029bd1945a9b8d7940ad1bb","original_commit_id":"fcaf088de953bcc2a029bd1945a9b8d7940ad1bb","user":{"login":"briankassouf","id":1916073,"avatar_url":"https://avatars.githubusercontent.com/u/1916073?v=3","gravatar_id":"","url":"https://api.github.com/users/briankassouf","html_url":"https://github.com/briankassouf","followers_url":"https://api.github.com/users/briankassouf/followers","following_url":"https://api.github.com/users/briankassouf/following{/other_user}","gists_url":"https://api.github.com/users/briankassouf/gists{/gist_id}","starred_url":"https://api.github.com/users/briankassouf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briankassouf/subscriptions","organizations_url":"https://api.github.com/users/briankassouf/orgs","repos_url":"https://api.github.com/users/briankassouf/repos","events_url":"https://api.github.com/users/briankassouf/events{/privacy}","received_events_url":"https://api.github.com/users/briankassouf/received_events","type":"User","site_admin":false},"body":"The spec recommends sending it in the authorization header, but reading headers from the transport is up to the implementation. \r\n\r\n> Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema. - https://jwt.io/introduction/#how-do-json-web-tokens-work-","created_at":"2016-08-24T19:11:48Z","updated_at":"2016-08-24T19:11:48Z","html_url":"https://github.com/go-kit/kit/pull/335#discussion_r76119830","pull_request_url":"https://api.github.com/repos/go-kit/kit/pulls/335","_links":{"self":{"href":"https://api.github.com/repos/go-kit/kit/pulls/comments/76119830"},"html":{"href":"https://github.com/go-kit/kit/pull/335#discussion_r76119830"},"pull_request":{"href":"https://api.github.com/repos/go-kit/kit/pulls/335"}}},"pull_request":{"url":"https://api.github.com/repos/go-kit/kit/pulls/335","id":80362126,"html_url":"https://github.com/go-kit/kit/pull/335","diff_url":"https://github.com/go-kit/kit/pull/335.diff","patch_url":"https://github.com/go-kit/kit/pull/335.patch","issue_url":"https://api.github.com/repos/go-kit/kit/issues/335","number":335,"state":"open","locked":false,"title":"[WIP] auth/jwt -- JWT service to service authentication","user":{"login":"briankassouf","id":1916073,"avatar_url":"https://avatars.githubusercontent.com/u/1916073?v=3","gravatar_id":"","url":"https://api.github.com/users/briankassouf","html_url":"https://github.com/briankassouf","followers_url":"https://api.github.com/users/briankassouf/followers","following_url":"https://api.github.com/users/briankassouf/following{/other_user}","gists_url":"https://api.github.com/users/briankassouf/gists{/gist_id}","starred_url":"https://api.github.com/users/briankassouf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briankassouf/subscriptions","organizations_url":"https://api.github.com/users/briankassouf/orgs","repos_url":"https://api.github.com/users/briankassouf/repos","events_url":"https://api.github.com/users/briankassouf/events{/privacy}","received_events_url":"https://api.github.com/users/briankassouf/received_events","type":"User","site_admin":false},"body":"Adds endpoint middleware for signing and parsing/validating JWT tokens. Also uses the RequestFunc & server/client before patterns to pass token data in and out of the context for remote calls and servers.\r\n\r\nuses the [github.com/dgrijalva/jwt-go](https://github.com/dgrijalva/jwt-go) library\r\n\r\nPlease comment on the design choices\r\n\r\ntodo:\r\n- [x] impliment endpoint middlewares\r\n- [x] write tests for middlewares\r\n- [x] grpc request funcs\r\n- [x] write tests for gprc funcs\r\n- [x] http request funcs\r\n- [x] write test for http request funcs\r\n- [ ] add more documentation\r\n- [ ] add JWT auth to addscv example?","created_at":"2016-08-07T09:00:20Z","updated_at":"2016-08-24T19:11:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"61b5c4ad94ecc1fded9a0a2bbf9a2d6a36c7fe30","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/go-kit/kit/pulls/335/commits","review_comments_url":"https://api.github.com/repos/go-kit/kit/pulls/335/comments","review_comment_url":"https://api.github.com/repos/go-kit/kit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/go-kit/kit/issues/335/comments","statuses_url":"https://api.github.com/repos/go-kit/kit/statuses/fcaf088de953bcc2a029bd1945a9b8d7940ad1bb","head":{"label":"briankassouf:auth/jwt","ref":"auth/jwt","sha":"fcaf088de953bcc2a029bd1945a9b8d7940ad1bb","user":{"login":"briankassouf","id":1916073,"avatar_url":"https://avatars.githubusercontent.com/u/1916073?v=3","gravatar_id":"","url":"https://api.github.com/users/briankassouf","html_url":"https://github.com/briankassouf","followers_url":"https://api.github.com/users/briankassouf/followers","following_url":"https://api.github.com/users/briankassouf/following{/other_user}","gists_url":"https://api.github.com/users/briankassouf/gists{/gist_id}","starred_url":"https://api.github.com/users/briankassouf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briankassouf/subscriptions","organizations_url":"https://api.github.com/users/briankassouf/orgs","repos_url":"https://api.github.com/users/briankassouf/repos","events_url":"https://api.github.com/users/briankassouf/events{/privacy}","received_events_url":"https://api.github.com/users/briankassouf/received_events","type":"User","site_admin":false},"repo":{"id":65063297,"name":"kit","full_name":"briankassouf/kit","owner":{"login":"briankassouf","id":1916073,"avatar_url":"https://avatars.githubusercontent.com/u/1916073?v=3","gravatar_id":"","url":"https://api.github.com/users/briankassouf","html_url":"https://github.com/briankassouf","followers_url":"https://api.github.com/users/briankassouf/followers","following_url":"https://api.github.com/users/briankassouf/following{/other_user}","gists_url":"https://api.github.com/users/briankassouf/gists{/gist_id}","starred_url":"https://api.github.com/users/briankassouf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/briankassouf/subscriptions","organizations_url":"https://api.github.com/users/briankassouf/orgs","repos_url":"https://api.github.com/users/briankassouf/repos","events_url":"https://api.github.com/users/briankassouf/events{/privacy}","received_events_url":"https://api.github.com/users/briankassouf/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/briankassouf/kit","description":"A standard library for microservices.","fork":true,"url":"https://api.github.com/repos/briankassouf/kit","forks_url":"https://api.github.com/repos/briankassouf/kit/forks","keys_url":"https://api.github.com/repos/briankassouf/kit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/briankassouf/kit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/briankassouf/kit/teams","hooks_url":"https://api.github.com/repos/briankassouf/kit/hooks","issue_events_url":"https://api.github.com/repos/briankassouf/kit/issues/events{/number}","events_url":"https://api.github.com/repos/briankassouf/kit/events","assignees_url":"https://api.github.com/repos/briankassouf/kit/assignees{/user}","branches_url":"https://api.github.com/repos/briankassouf/kit/branches{/branch}","tags_url":"https://api.github.com/repos/briankassouf/kit/tags","blobs_url":"https://api.github.com/repos/briankassouf/kit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/briankassouf/kit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/briankassouf/kit/git/refs{/sha}","trees_url":"https://api.github.com/repos/briankassouf/kit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/briankassouf/kit/statuses/{sha}","languages_url":"https://api.github.com/repos/briankassouf/kit/languages","stargazers_url":"https://api.github.com/repos/briankassouf/kit/stargazers","contributors_url":"https://api.github.com/repos/briankassouf/kit/contributors","subscribers_url":"https://api.github.com/repos/briankassouf/kit/subscribers","subscription_url":"https://api.github.com/repos/briankassouf/kit/subscription","commits_url":"https://api.github.com/repos/briankassouf/kit/commits{/sha}","git_commits_url":"https://api.github.com/repos/briankassouf/kit/git/commits{/sha}","comments_url":"https://api.github.com/repos/briankassouf/kit/comments{/number}","issue_comment_url":"https://api.github.com/repos/briankassouf/kit/issues/comments{/number}","contents_url":"https://api.github.com/repos/briankassouf/kit/contents/{+path}","compare_url":"https://api.github.com/repos/briankassouf/kit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/briankassouf/kit/merges","archive_url":"https://api.github.com/repos/briankassouf/kit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/briankassouf/kit/downloads","issues_url":"https://api.github.com/repos/briankassouf/kit/issues{/number}","pulls_url":"https://api.github.com/repos/briankassouf/kit/pulls{/number}","milestones_url":"https://api.github.com/repos/briankassouf/kit/milestones{/number}","notifications_url":"https://api.github.com/repos/briankassouf/kit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/briankassouf/kit/labels{/name}","releases_url":"https://api.github.com/repos/briankassouf/kit/releases{/id}","deployments_url":"https://api.github.com/repos/briankassouf/kit/deployments","created_at":"2016-08-06T03:36:09Z","updated_at":"2016-08-06T03:36:11Z","pushed_at":"2016-08-18T06:36:22Z","git_url":"git://github.com/briankassouf/kit.git","ssh_url":"git@github.com:briankassouf/kit.git","clone_url":"https://github.com/briankassouf/kit.git","svn_url":"https://github.com/briankassouf/kit","homepage":"http://gokit.io","size":4934,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"go-kit:master","ref":"master","sha":"803166ff08662870111f3420944200203a06629e","user":{"login":"go-kit","id":10981023,"avatar_url":"https://avatars.githubusercontent.com/u/10981023?v=3","gravatar_id":"","url":"https://api.github.com/users/go-kit","html_url":"https://github.com/go-kit","followers_url":"https://api.github.com/users/go-kit/followers","following_url":"https://api.github.com/users/go-kit/following{/other_user}","gists_url":"https://api.github.com/users/go-kit/gists{/gist_id}","starred_url":"https://api.github.com/users/go-kit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-kit/subscriptions","organizations_url":"https://api.github.com/users/go-kit/orgs","repos_url":"https://api.github.com/users/go-kit/repos","events_url":"https://api.github.com/users/go-kit/events{/privacy}","received_events_url":"https://api.github.com/users/go-kit/received_events","type":"Organization","site_admin":false},"repo":{"id":30215630,"name":"kit","full_name":"go-kit/kit","owner":{"login":"go-kit","id":10981023,"avatar_url":"https://avatars.githubusercontent.com/u/10981023?v=3","gravatar_id":"","url":"https://api.github.com/users/go-kit","html_url":"https://github.com/go-kit","followers_url":"https://api.github.com/users/go-kit/followers","following_url":"https://api.github.com/users/go-kit/following{/other_user}","gists_url":"https://api.github.com/users/go-kit/gists{/gist_id}","starred_url":"https://api.github.com/users/go-kit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-kit/subscriptions","organizations_url":"https://api.github.com/users/go-kit/orgs","repos_url":"https://api.github.com/users/go-kit/repos","events_url":"https://api.github.com/users/go-kit/events{/privacy}","received_events_url":"https://api.github.com/users/go-kit/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/go-kit/kit","description":"A standard library for microservices.","fork":false,"url":"https://api.github.com/repos/go-kit/kit","forks_url":"https://api.github.com/repos/go-kit/kit/forks","keys_url":"https://api.github.com/repos/go-kit/kit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-kit/kit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-kit/kit/teams","hooks_url":"https://api.github.com/repos/go-kit/kit/hooks","issue_events_url":"https://api.github.com/repos/go-kit/kit/issues/events{/number}","events_url":"https://api.github.com/repos/go-kit/kit/events","assignees_url":"https://api.github.com/repos/go-kit/kit/assignees{/user}","branches_url":"https://api.github.com/repos/go-kit/kit/branches{/branch}","tags_url":"https://api.github.com/repos/go-kit/kit/tags","blobs_url":"https://api.github.com/repos/go-kit/kit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-kit/kit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-kit/kit/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-kit/kit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-kit/kit/statuses/{sha}","languages_url":"https://api.github.com/repos/go-kit/kit/languages","stargazers_url":"https://api.github.com/repos/go-kit/kit/stargazers","contributors_url":"https://api.github.com/repos/go-kit/kit/contributors","subscribers_url":"https://api.github.com/repos/go-kit/kit/subscribers","subscription_url":"https://api.github.com/repos/go-kit/kit/subscription","commits_url":"https://api.github.com/repos/go-kit/kit/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-kit/kit/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-kit/kit/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-kit/kit/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-kit/kit/contents/{+path}","compare_url":"https://api.github.com/repos/go-kit/kit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-kit/kit/merges","archive_url":"https://api.github.com/repos/go-kit/kit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-kit/kit/downloads","issues_url":"https://api.github.com/repos/go-kit/kit/issues{/number}","pulls_url":"https://api.github.com/repos/go-kit/kit/pulls{/number}","milestones_url":"https://api.github.com/repos/go-kit/kit/milestones{/number}","notifications_url":"https://api.github.com/repos/go-kit/kit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-kit/kit/labels{/name}","releases_url":"https://api.github.com/repos/go-kit/kit/releases{/id}","deployments_url":"https://api.github.com/repos/go-kit/kit/deployments","created_at":"2015-02-03T00:01:19Z","updated_at":"2016-08-24T18:14:31Z","pushed_at":"2016-08-23T13:46:53Z","git_url":"git://github.com/go-kit/kit.git","ssh_url":"git@github.com:go-kit/kit.git","clone_url":"https://github.com/go-kit/kit.git","svn_url":"https://github.com/go-kit/kit","homepage":"https://gokit.io","size":8256,"stargazers_count":4993,"watchers_count":4993,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":402,"mirror_url":null,"open_issues_count":24,"forks":402,"open_issues":24,"watchers":4993,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/go-kit/kit/pulls/335"},"html":{"href":"https://github.com/go-kit/kit/pull/335"},"issue":{"href":"https://api.github.com/repos/go-kit/kit/issues/335"},"comments":{"href":"https://api.github.com/repos/go-kit/kit/issues/335/comments"},"review_comments":{"href":"https://api.github.com/repos/go-kit/kit/pulls/335/comments"},"review_comment":{"href":"https://api.github.com/repos/go-kit/kit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/go-kit/kit/pulls/335/commits"},"statuses":{"href":"https://api.github.com/repos/go-kit/kit/statuses/fcaf088de953bcc2a029bd1945a9b8d7940ad1bb"}}}}
{"actor":{"display_login":"briankassouf"}}