Skip to content
This repository has been archived by the owner on Mar 18, 2022. It is now read-only.

Commit

Permalink
Merge f1c5e0a into e6efad3
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasRoesler committed Jan 29, 2018
2 parents e6efad3 + f1c5e0a commit 8b44572
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 24 deletions.
3 changes: 1 addition & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ CreateToken takes some claims and a key (either private rsa, private ec or hmac
#### func GetTokenFromRequest

```go
func GetTokenFromRequest(r *http.Request) (string, error)
func GetTokenFromRequest(r *http.Request) (TokenPrefix, string, error)
```
GetTokenFromRequest takes the first Authorization header and extracts the bearer
json web token
Expand Down Expand Up @@ -64,7 +64,7 @@ ParsePublicKey parses a pem encoded public key (rsa or ecdsa based)
#### func GetClaimsFromRequest

```go
func GetClaimsFromRequest(r *http.Request, key interface{}) (Claims, error)
func GetClaimsFromRequest(r *http.Request, key interface{}) (TokenPrefix, Claims, error)
```
GetClaimsFromRequest extracts and validates the token from a request, returning the claims

Expand Down
52 changes: 40 additions & 12 deletions jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import (
"net/http"
"strings"

"github.com/dgrijalva/jwt-go"
jwt "github.com/dgrijalva/jwt-go"
)

const (
// AuthorizationHeader is the constant string used to get the Authorization
// headers
AuthorizationHeader = "Authorization"
)

// Claims is a map of string->something containing the meta infos associated with a token
Expand Down Expand Up @@ -125,21 +131,43 @@ func ParsePrivateKey(data []byte) (interface{}, error) {
return rsaKey, nil
}

// GetTokenFromRequest takes the first Authorization header and extracts the bearer json web token
func GetTokenFromRequest(r *http.Request) (string, error) {
authHeader := r.Header.Get("Authorization")
parts := strings.Split(authHeader, " ")
if len(parts) != 2 {
return "", errors.New("no valid authorization header")
// GetTokenFromRequest takes the first Authorization header or `token` GET pararm , then
// extract the token prefix and json web token
func GetTokenFromRequest(r *http.Request) (prefix string, token string, err error) {

tokenList, ok := r.Header[AuthorizationHeader]
// pull from GET if not in the headers
if !ok || len(tokenList) < 1 {
tokenList, ok = r.URL.Query()["token"]
prefix = "GET"
}

if len(tokenList) < 1 {
prefix = ""
return prefix, token, errors.New("no valid authorization header")
}
return parts[1], nil

tokenParts := strings.Fields(tokenList[0])
switch len(tokenParts) {
case 1:
token = tokenParts[0]
case 2:
prefix = tokenParts[0]
token = tokenParts[1]
default:
return prefix, token, errors.New("invalid token: unexpected number of parts")
}

return prefix, token, nil
}

// GetClaimsFromRequest extracts and validates the token from a request, returning the claims
func GetClaimsFromRequest(r *http.Request, key interface{}) (Claims, error) {
token, err := GetTokenFromRequest(r)
func GetClaimsFromRequest(r *http.Request, key interface{}) (prefix string, claims Claims, err error) {
prefix, token, err := GetTokenFromRequest(r)
if err != nil {
return nil, err
return prefix, nil, err
}
return ValidateToken(token, key)

claims, err = ValidateToken(token, key)
return prefix, claims, err
}
2 changes: 1 addition & 1 deletion jwt_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jwt_test
package jwt

import (
"testing"
Expand Down
59 changes: 52 additions & 7 deletions jwt_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jwt_test
package jwt

import (
"io/ioutil"
Expand All @@ -7,8 +7,6 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

. "github.com/Contiamo/jwt"
)

var _ = Describe("JWT", func() {
Expand Down Expand Up @@ -97,10 +95,46 @@ var _ = Describe("JWT", func() {
token, err := CreateToken(claims, privKey)
Expect(err).NotTo(HaveOccurred())
r, _ := http.NewRequest("GET", "http://foobar.com", nil)
r.Header.Add("Authorization", "bearer "+token)
reClaims, err := GetClaimsFromRequest(r, pubKey)
r.Header.Add("Authorization", "Bearer "+token)
prefix, reClaims, err := GetClaimsFromRequest(r, pubKey)
Expect(err).NotTo(HaveOccurred())
Expect(reClaims).To(Equal(claims))
Expect(prefix).To(Equal("Bearer"))
})

It("should be possible to get a token from a http requests authorization header with Token prefix", func() {
claims := Claims{"foo": "bar"}
pubKey, err := ParsePublicKey(rsaPubKey)
Expect(err).NotTo(HaveOccurred())
privKey, err := ParsePrivateKey(rsaPrivKey)
Expect(err).NotTo(HaveOccurred())
token, err := CreateToken(claims, privKey)
Expect(err).NotTo(HaveOccurred())
r, _ := http.NewRequest("GET", "http://foobar.com", nil)
r.Header.Add("Authorization", "Token "+token)
prefix, reClaims, err := GetClaimsFromRequest(r, pubKey)
Expect(err).NotTo(HaveOccurred())
Expect(reClaims).To(Equal(claims))
Expect(prefix).To(Equal("Token"))
})

It("should be possible to get a token from a http requests get parameter", func() {
claims := Claims{"foo": "bar"}
pubKey, err := ParsePublicKey(rsaPubKey)
Expect(err).NotTo(HaveOccurred())
privKey, err := ParsePrivateKey(rsaPrivKey)
Expect(err).NotTo(HaveOccurred())
token, err := CreateToken(claims, privKey)
Expect(err).NotTo(HaveOccurred())
r, _ := http.NewRequest("GET", "http://foobar.com", nil)
q := r.URL.Query()
q.Add("token", token)
r.URL.RawQuery = q.Encode()

prefix, reClaims, err := GetClaimsFromRequest(r, pubKey)
Expect(err).NotTo(HaveOccurred())
Expect(reClaims).To(Equal(claims))
Expect(prefix).To(Equal("GET"))
})

It("should NOT be possible to get a token from a http requests authorization header if the header is malformed", func() {
Expand All @@ -112,10 +146,21 @@ var _ = Describe("JWT", func() {
token, err := CreateToken(claims, privKey)
Expect(err).NotTo(HaveOccurred())
r, _ := http.NewRequest("GET", "http://foobar.com", nil)
r.Header.Add("Authorization", token)
reClaims, err := GetClaimsFromRequest(r, pubKey)
r.Header.Add("Authorization", "bearder "+token+" garbage")
prefix, reClaims, err := GetClaimsFromRequest(r, pubKey)
Expect(err).To(HaveOccurred())
Expect(reClaims).To(BeEmpty())
Expect(prefix).To(BeEmpty())
})

It("should NOT be possible to get a token from a http requests authorization header if the token is missing", func() {
pubKey, err := ParsePublicKey(rsaPubKey)
Expect(err).NotTo(HaveOccurred())
r, _ := http.NewRequest("GET", "http://foobar.com", nil)
prefix, reClaims, err := GetClaimsFromRequest(r, pubKey)
Expect(err).To(HaveOccurred())
Expect(reClaims).To(BeEmpty())
Expect(prefix).To(BeEmpty())
})

It("should NOT be possible to create a token with a wrong key type", func() {
Expand Down

0 comments on commit 8b44572

Please sign in to comment.