Giter Club home page Giter Club logo

jwt's Introduction

jwt

build-img pkg-img reportcard-img coverage-img version-img

JSON Web Token for Go RFC 7519, also see jwt.io for more.

The latest version is v5.

Rationale

There are many JWT libraries, but many of them are hard to use (unclear or fixed API), not optimal (unneeded allocations + strange API). This library addresses all these issues. It's simple to read, to use, memory and CPU conservative.

Features

  • Simple API.
  • Clean and tested code.
  • Optimized for speed.
  • Concurrent-safe.
  • Dependency-free.
  • All well-known algorithms are supported
    • HMAC (HS)
    • RSA (RS)
    • RSA-PSS (PS)
    • ECDSA (ES)
    • EdDSA (EdDSA)
    • or your own!

See GUIDE.md for more details.

Install

Go version 1.17+

go get github.com/cristalhq/jwt/v5

Example

Build new token:

// create a Signer (HMAC in this example)
key := []byte(`secret`)
signer, err := jwt.NewSignerHS(jwt.HS256, key)
checkErr(err)

// create claims (you can create your own, see: ExampleBuilder_withUserClaims)
claims := &jwt.RegisteredClaims{
    Audience: []string{"admin"},
    ID:       "random-unique-string",
}

// create a Builder
builder := jwt.NewBuilder(signer)

// and build a Token
token, err := builder.Build(claims)
checkErr(err)

// here is token as a string
var _ string = token.String()

Parse and verify token:

// create a Verifier (HMAC in this example)
key := []byte(`secret`)
verifier, err := jwt.NewVerifierHS(jwt.HS256, key)
checkErr(err)

// parse and verify a token
tokenBytes := token.Bytes()
newToken, err := jwt.Parse(tokenBytes, verifier)
checkErr(err)

// or just verify it's signature
err = verifier.Verify(newToken)
checkErr(err)

// get Registered claims
var newClaims jwt.RegisteredClaims
errClaims := json.Unmarshal(newToken.Claims(), &newClaims)
checkErr(errClaims)

// or parse only claims
errParseClaims := jwt.ParseClaims(tokenBytes, verifier, &newClaims)
checkErr(errParseClaims)

// verify claims as you wish
var _ bool = newClaims.IsForAudience("admin")
var _ bool = newClaims.IsValidAt(time.Now())

Also see examples: example_test.go.

Documentation

See these docs.

License

MIT License.

jwt's People

Contributors

bcongdon avatar benzolium avatar cristaloleg avatar danikarik avatar dependabot[bot] avatar dipandaaser avatar fzambia avatar hoodelliot avatar kamalashreen avatar kingfargrace avatar lil5 avatar paulish avatar shoanchikato avatar storozhukbm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jwt's Issues

Cannot find package "github.com/cristalhq/jwt/v3"

Dear sir, could you please help me to understand how to install your package?
I'm very new in Go, so maybe missing some simple thing here

C:\Users\bob\go>go version
go version go1.14.6 windows/amd64

C:\Users\bob\go>go env GOROOT
D:\software\Go

C:\Users\bob\go>go env GOPATH
C:\Users\bob\go

C:\Users\bob\go>go get -v -u github.com/golang/example/hello
github.com/golang/example (download)

C:\Users\bob\go>%GOPATH%/bin/hello
Hello, Go examples!

C:\Users\bob\go>go get -v -u github.com/cristalhq/jwt/v3
github.com/cristalhq/jwt (download)
package github.com/cristalhq/jwt/v3: cannot find package "github.com/cristalhq/jwt/v3" in any of:
        D:\software\Go\src\github.com\cristalhq\jwt\v3 (from $GOROOT)
        C:\Users\bob\go\src\github.com\cristalhq\jwt\v3 (from $GOPATH)

Optimisation causing incorrect header to encode

encodeHeader in build.go checks if the header is a JWT, and then chooses a pre-encoded header as the result, as an optimization. However, a Header can also have a cty field or a kid field. AND, if either of these are set, the optimization will not encode them.

I Suggest the if header.Type check also needs to ensure cty and kid are not set.

This is the function in question.

func encodeHeader(header *Header) []byte {
	if header.Type == "JWT" {
		switch header.Algorithm {
		case NoEncryption:
			return []byte("eyJhbGciOiJub25lIn0")
		case EdDSA:
			return []byte("eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9")

Add Parsing tests

Before starting work on this issue, please, add a comment here.

It will be enough to create few test cases for valid and invalid JWT tokens.

IsValidAt with CustomClaims ?

I created a CustomClaim:

type userClaims struct {
	RegisteredClaims jwt.RegisteredClaims
	Some             string
}

with:

claims := &userClaims{
	RegisteredClaims: jwt.RegisteredClaims{
		ExpiresAt: jwt.NewNumericDate(time_exp),
		NotBefore: jwt.NewNumericDate(time_nbf),
	},
	Some: some_value,
}

where time_exp and time_nbf are time.Time and some_value is a string.

I get the registered Claims doing this:

var regClaims jwt.RegisteredClaims
errParseClaims := jwt.ParseClaims(tokenBytes, verifier, &regClaims)
is_valid := regClaims.IsValidAt(time.Now())

I can build and parse the token.
I want to check the exp and nbf using "IsValidAt(time.Now())".
But it is always true.
When I tried "IsValidAt(time.Now())" with the regular claims it worked.

example.:
token.String():
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJSZWdpc3RlcmVkQ2xhaW1zIjp7ImV4cCI6MjAwMDAwMDAwMCwibmJmIjoxNjcyODQzNzYwfSwiU29tZSI6IiJ9. 0piI7l7NlmrmGuEm5tjMvIQTpFDZTsXkwO78HG8AC8E
string(token.Claims):
{"RegisteredClaims":{"exp":2000000000,"nbf":1000000000},"Some":""}
is_valid: true

Add fuzzing

Currently there is no real need of fuzzing, all the text/binary operations are simple and obvious, but it might change.

So adding gofuzz should make module more robust and safe.

Please, do not commit corpus directory, 1 file with Fuzz function should be enough ๐Ÿ˜‰

JWK Set jwt.Verifier implementation

I'm looking to create a separate helper Go package for this project. This helper Go package will verify JWTs are signed with a key in a JWK Set (JWKS). It helps users of this package by turning a JWKS into a jwt.Verifier to more conveniently verify keys.

This would be similar to how github.com/MicahParks/keyfunc is a helper Go package for github.com/golang-jwt/jwt/v4.

However, the jwt.Verifier interface has a method called Algorithm that must be implemented. From the Go docs, I can't infer how to implement this method, but looking at the source code, it seems to me that the jwt.Algorithm return parameter's value is the set of values I often see as the "alg" in JWT headers. Also glancing at the source code, it seems to me that the only use of the Algorithm method is in a _test.go file, so I'm not sure if an improper implementation of this method would affect anything.

Before I continue developing this package, I wanted to confirm how to implement this Algorithm method, due to the fact that it's a part of the public facing API. Since a JWKS can contain multiple key types, it's not appropriate to return a single "alg" value. Perhaps one of the two options may be ideal?

  1. Add a new jwt.Algorithm value that indicates any algorithm can be verified.
  2. Remove the Algorithm method from the jwt.Verifier interface (would be a breaking change and require a major semver bump).

KeyID support for RFC7517

Hi!

I've created PR in Centrifigo which uses your package as a dependency. What I'm trying to add is support for JWKS where encryption keys are rotating and to fetch appropriate public key kid header is used. See RFC

There is a problem with current Header which doesn't contain KeyID property. Previously it was presented in centrifugal/centrifugo#410.

I can create PR for that.

Crypto Go ๏ผšwe are a research group to help developers build secure applications.

Hi, we are a research group to help developers build secure applications. We designed a cryptographic misuse detector (i.e., CryptoGo) on Go language. We found your great public repository from Github, and several security issues detected by CryptoGo are shown in the following.
Note that the cryptographic algorithms are categorized with two aspects: security strength and security vulnerability based on NIST Special Publication 800-57 and other public publications. Moreover, CryptoGo defined certain rules derived from the APIs of Go cryptographic library and other popular cryptographic misuse detectors. The specific security issues we found are as follows:
Location: algo_rs.go:79;
Broken rule: R-07: RSASSA-PKCS1-v1_5 is deprecated;
We wish the above security issues could truly help you to build a secure application. If you have any concern or suggestion, please feel free to contact us, we are looking forward to your reply. Thanks.

Add clear warnings for HS256 secret length

https://auth0.com/blog/brute-forcing-hs256-is-possible-the-importance-of-using-strong-keys-to-sign-jwts/

The second key, secret is 48-bit. This is simply too short to be a valid key. In fact, the JSON Web Algorithms RFC 7518 states that a key of the same size as the hash output (for instance, 256 bits for "HS256") or larger MUST be used with the HS256 algorithm.

I therefore recommend that anyone trying to generate a JSON Web token and signing them with HS256 to use a properly sized secret key. Auth0 secret keys are 512 bits in length and not susceptible to this type of brute force attack.

I see too many examples using secret as a key without any warnings, please consider adding an example how to generate such key.

"Get started" in README?

I'd like to try this JWT library but I don't know how to start. Please write a small usage example in README.

Version v5.2.0 is breaking our code

Hi,

We upgraded to v5.2.0 and our JWT tokens no longer parse as they do not contain the JWT header type (and I don't think that we can get this fixed any time soon).

This is the commit that broke us: 14ac6af

Is there any chance of making this test optional?

Thanks

Slow Sign

No benchmarks so I did a small comparison.

goos: darwin
goarch: amd64
pkg: github.com/pascaldekloe/jwt
BenchmarkCristalHQ/sign-HS256-4         	  543394	      2212 ns/op
BenchmarkCristalHQ/check-HS256-4        	  271428	      4300 ns/op
BenchmarkHMAC/sign-HS256-4              	  589506	      2034 ns/op	       123 B/token
BenchmarkHMAC/check-HS256-4             	  274357	      4277 ns/op
PASS
ok  	github.com/pascaldekloe/jwt	5.242s
func BenchmarkCristalHQ(b *testing.B) {
        // 512-bit key
        secret := make([]byte, 64)

        signer, err := cjwt.NewHS256(secret)
        if err != nil {
                b.Fatal(err)
        }
        builder := cjwt.NewTokenBuilder(signer)

        claims := &cjwt.StandardClaims{
                Issuer: benchClaims.Issuer,
                IssuedAt: cjwt.Timestamp(*benchClaims.Issued),
        }

        var token []byte
        b.Run("sign-HS256", func(b *testing.B) {
                for i := 0; i < b.N; i++ {
                        obj, err := builder.Build(claims)
                        if err != nil {
                                b.Fatal(err)
                        }
                        token = obj.Raw()
                }
        })
        b.Run("check-HS256", func(b *testing.B) {
                for i := 0; i < b.N; i++ {
                        obj, err := cjwt.ParseAndVerify(token, signer)
                        if err != nil {
                                b.Fatal(err)
                        }
                        err = json.Unmarshal(obj.RawClaims(), new(map[string]interface{}))
                        if err != nil {
                                b.Fatal(err)
                        }
                }
        })
}

The jwt format is incorrect and panic directly

err = verifier.Verify(token.Payload(), token.Signature())

Once the JWT format of the previous Token input is incorrect, this code will immediately panic
Go1.17

Error message:
`panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x10 pc=0xbb6c0a]

goroutine 1 [running]:
github.com/cristalhq/jwt/v3.(*Token).Payload(...)
C:/Users/SKER/go/pkg/mod/github.com/cristalhq/jwt/[email protected]/jwt.go:52
ncovGin/tools.VerifyToken({0xe2f985, 0xc000046000})
C:/go-src/ncovGin/tools/jwt.go:63 +0x6a
main.main()
C:/go-src/ncovGin/test/test.go:14 +0x25
`

v2 preparations

  • fix and simplify validations
  • verify RFC for time format
  • ...

Error in readme -> Parse and verify token exemple

In Parse and verify token exemple line 12.
is actually golang err = verifier.Verify(token) but is doesn't work because Verify Need two arguments.
We can replace with golang err = verifier.Verify(token.Payload(), token.Signature())

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.