Skip to content

Instantly share code, notes, and snippets.

@nanoninja
Created September 29, 2016 14:35
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save nanoninja/50e56791d13d340068ccf4f6c810dbf7 to your computer and use it in GitHub Desktop.
Save nanoninja/50e56791d13d340068ccf4f6c810dbf7 to your computer and use it in GitHub Desktop.
JOSE - JWT Usage Examples

JOSE - JWT Usage Examples

JOSE is a comprehensive set of JWT, JWS, and JWE libraries.

jwt.io

Installation

go get github.com/SermoDigital/jose

Building rsa keys

Private key

openssl genrsa -out sample_key.priv 2048

Public key

openssl rsa -in sample_key.priv -pubout > sample_key.pub

Usage Examples

Using Claims

package main

import (
	"fmt"
	"time"

	"github.com/SermoDigital/jose/jws"
)

func main() {
	// expires in 10 seconds
	expires := time.Now().Add(time.Duration(10) * time.Second)

	claims := jws.Claims{}
	claims.SetExpiration(expires)
	claims.SetIssuedAt(time.Now())

	fmt.Println(claims)
}

Generating token

After generating up your private and public key.

package main

import (
	"fmt"
	"io/ioutil"
	"time"

	"github.com/SermoDigital/jose/crypto"
	"github.com/SermoDigital/jose/jws"
)

func main() {
	bytes, _ := ioutil.ReadFile("./sample_key.priv")

	claims := jws.Claims{}
	claims.SetExpiration(time.Now().Add(time.Duration(10) * time.Second))

	rsaPrivate, _ := crypto.ParseRSAPrivateKeyFromPEM(bytes)
	jwt := jws.NewJWT(claims, crypto.SigningMethodRS256)

	b, _ := jwt.Serialize(rsaPrivate)
	fmt.Printf("%s", b)
}

Validating token

package main

import (
	"io/ioutil"
	"log"

	"github.com/SermoDigital/jose/crypto"
	"github.com/SermoDigital/jose/jws"
)

func main() {
	bytes, _ := ioutil.ReadFile("./sample_key.pub")
	rsaPublic, _ := crypto.ParseRSAPublicKeyFromPEM(bytes)

	accessToken := "YOUR ACCESS TOKEN FROM COOKIE, FORM, HEADERS..."
	jwt, err := jws.ParseJWT([]byte(accessToken))
	if err != nil {
		log.Fatal(err)
	}

	// Validate token
	if err = jwt.Validate(rsaPublic, crypto.SigningMethodRS256); err != nil {
		log.Fatal(err)
	}
}

Parsing token

You must choose a Format to parse an access token

From Header

package main

import (
	"fmt"
	"net/http"

	"github.com/SermoDigital/jose/jws"
)

func ParseTokenHandler(rw http.ResponseWriter, r *http.Request) {
	j, err := jws.ParseFromHeader(r, jws.General)

	// Validate token here...
	// j.Validate(rsaPublic, crypto.SigningMethodRS256)
}

func main() {
	http.HandleFunc("/", ParseTokenHandler)
	http.ListenAndServe(":3000", nil)
}

From Request

JWSFormKey is the form "key" which should be used inside ParseFromRequest if the request is a multipart.Form.

j, err := jws.ParseFromRequest(r, jws.General)

From Form

j, err := jws.ParseFromForm(r, jws.General)
@everton-sales-branco
Copy link

Based in that I developed a middleware:
How can I unmarshal the payload into your payloadJWT type?


type payloadJWT struct {
	exp     int64   `json:"exp"`
	user	string  `json:"user"`
}


func Checktoken(next http.Handler) http.Handler {

	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		// test mode
			bytes, _ := ioutil.ReadFile("./cert/token.pub")
			rsaPublic, _ := crypto.ParseRSAPublicKeyFromPEM(bytes)
		//

		token, err := jws.ParseFromHeader(req, jws.Compact)
		if err != nil {
			log.Fatal(err)
		}

		if err = token.Verify(rsaPublic, crypto.SigningMethodRS256); err != nil {
			fmt.Println("O token é inválido.")
			log.Fatal(err)
		} else {
			var payload payloadJWT
			
			
			//payload <= token.Payload()


			fmt.Println("User: ", payload.user)
			next.ServeHTTP(rw, req)
		}

	})
}


@DarkArtistry
Copy link

bytes, _ := ioutil.ReadFile("./cert/token.pub") << what if i have a string value ?

@DarkArtistry
Copy link

instead of reading a PEM file

@NeleOb
Copy link

NeleOb commented Dec 30, 2022

Hi, I am trying to run your example code for using claims.
I did:

go get github.com/SermoDigital/jose
package main

import (
	"fmt"
	"time"

	"github.com/SermoDigital/jose/jws"
)

func main() {
	// expires in 10 seconds
	expires := time.Now().Add(time.Duration(10) * time.Second)

	claims := jws.Claims{}
	claims.SetExpiration(expires)
	claims.SetIssuedAt(time.Now())

	fmt.Println(claims)
}

But i get the following erros messages when i run the code.

claims.SetExpiration undefined (type jws.Claims has no field or method SetExpiration)
claims.SetIssuedAt undefined (type jws.Claims has no field or method SetIssuedAt)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment