Skip to content
/ token Public

A Go module for seamless JWT & PASETO token integration

License

Notifications You must be signed in to change notification settings

fsobh/token

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

65 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Authentication token module for Golang

license coverage last-commit repo-top-language repo-language-count

Built with the tools and technologies:

Go GitHub%20Actions


πŸ”— Table of Contents


πŸ“ Overview

A Go module for seamless JWT & PASETO token integration


πŸ‘Ύ Features

  • JWT
  • PASETO V2
  • PASETO V3

πŸ“ Project Structure

└── token/
    β”œβ”€β”€ .github
    β”‚   └── workflows
    β”‚       └── test-and-coverage.yml
    β”œβ”€β”€ LICENSE.txt
    β”œβ”€β”€ README.MD
    β”œβ”€β”€ coverage.svg
    β”œβ”€β”€ go.mod
    β”œβ”€β”€ go.sum
    β”œβ”€β”€ jwt_asym_maker.go
    β”œβ”€β”€ jwt_asym_maker_test.go
    β”œβ”€β”€ jwt_maker.go
    β”œβ”€β”€ jwt_maker_test.go
    β”œβ”€β”€ main
    β”‚   β”œβ”€β”€ demo
    β”‚   β”‚   β”œβ”€β”€ util.go
    β”‚   β”‚   β”œβ”€β”€ v2.go
    β”‚   β”‚   └── v3.go
    β”‚   └── test.go
    β”œβ”€β”€ makefile
    β”œβ”€β”€ maker.go
    β”œβ”€β”€ paseto_v2_local_maker.go
    β”œβ”€β”€ paseto_v2_local_maker_test.go
    β”œβ”€β”€ paseto_v2_public_maker.go
    β”œβ”€β”€ paseto_v2_public_maker_test.go
    β”œβ”€β”€ paseto_v3_local_maker.go
    β”œβ”€β”€ paseto_v3_local_maker_test.go
    β”œβ”€β”€ paseto_v3_public_maker.go
    β”œβ”€β”€ paseto_v3_public_maker_test.go
    β”œβ”€β”€ payload.go
    β”œβ”€β”€ payload_test.go
    └── testCoverage.out

πŸ“‚ Project Index

token/
__root__
LICENSE.txt ❯ License file
jwt_maker.go ❯ Token maker for Symmetric JWT tokens
maker.go ❯ Token maker interface
paseto_v3_local_maker_test.go ❯ Test file
jwt_asym_maker_test.go ❯ Test file
makefile ❯ make file for tests
paseto_v2_public_maker.go ❯ Token maker for Paseto V2 Public tokens (Asymmetrical)
go.mod ❯ go mod file
jwt_maker_test.go ❯ Test file
go.sum ❯ go sum
paseto_v2_public_maker_test.go ❯ Test file
paseto_v2_local_maker.go ❯ Token maker for Paseto V2 Local tokens (Symmetrical)
paseto_v3_local_maker.go ❯ Token maker for Paseto V3 Local tokens (Symmetrical)
payload.go ❯ Predefined payload with username and token id fields
testCoverage.out ❯ Test coverage results
jwt_asym_maker.go ❯ Token maker for Asymmetric JWT tokens
payload_test.go ❯ Test file
paseto_v2_local_maker_test.go ❯ Test file
paseto_v3_public_maker_test.go ❯ Test file
paseto_v3_public_maker.go ❯ Token maker for Paseto V3 Public tokens (Asymmetrical)
README.MD ❯ Documentation
.github
workflows
test-and-coverage.yml ❯ Work flow to run unit tests (on push) and update readme with test coverage badge
main
test.go ❯ Playground file for development
demo
util.go ❯ Playground file for development
v3.go ❯ Playground file for development
v2.go ❯ Playground file for development

πŸš€ Getting Started

β˜‘οΈ Prerequisites

Before getting started with token, ensure your runtime environment meets the following requirements:

  • Programming Language: Go
  • Package Manager: Go modules

βš™οΈ Installation

Install the project dependencies:

Using go modules Β 

❯ go get github.com/fsobh/token

πŸ€– Usage

  • Paseto V2
package main

import (
	"aidanwoods.dev/go-paseto"
	"encoding/json"
	"fmt"
	"github.com/fsobh/token"
	"log"

	"time"
)

func toJSON(data interface{}) string {
	jsonBytes, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		log.Fatalf("Failed to marshal to JSON: %v", err)
	}
	return string(jsonBytes)
}

func main() {

	// ** Paseto V2 Local **

	// Generate Keys
	symmetricKeyV2 := paseto.NewV2SymmetricKey()

	// convert keys to Hex
	symmetricKeyStringV2 := symmetricKeyV2.ExportHex()

	localMakerV2, err := token.NewPasetoV2Local(symmetricKeyStringV2)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V2 local token maker: %w", err)
	}

	localTokenStringV2, localPayloadV2, err := localMakerV2.CreateToken("alice", 24*time.Hour)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V2 local token: %w", err)
	}

	fmt.Println("Created Paseto V2 local Token (JSON):")
	fmt.Println(toJSON(map[string]interface{}{
		"token":      localTokenStringV2,
		"payload":    localPayloadV2,
		"expiration": localPayloadV2.ExpiredAt,
	}))

	// Verify the token
	verifiedPayload, err := localMakerV2.VerifyToken(localTokenStringV2)
	if err != nil {
		_ = fmt.Errorf("failed to verify Paseto V2 local token: %w", err)
	}

	// Display verified payload in JSON
	fmt.Println("Verified Paseto V2 local Payload (JSON):")
	fmt.Println(toJSON(verifiedPayload))




	// ** Paseto V2 Public **

	// generate keys
	privateKeyV2 := paseto.NewV2AsymmetricSecretKey()
	publicKeyV2 := privateKeyV2.Public()

	// convert keys to Hex
	privateKeyStringV2 := privateKeyV2.ExportHex()
	publicKeyStringV2 := publicKeyV2.ExportHex()

	publicMakerV2, err := token.NewPasetoV2Public(privateKeyStringV2, publicKeyStringV2)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V2 public token maker: %w", err)
	}


	publicTokenStringV2, publicPayloadV2, err := publicMakerV2.CreateToken("charlie", 24*time.Hour)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V2 public token: %w", err)
	}


	fmt.Println("Created Paseto V2 public Token (JSON):")
	fmt.Println(toJSON(map[string]interface{}{
		"token":      publicTokenStringV2,
		"payload":    publicPayloadV2,
		"expiration": publicPayloadV2.ExpiredAt,
	}))


	publicVerifiedPayloadV2, err := publicMakerV2.VerifyToken(publicTokenStringV2)
	if err != nil {
		_ = fmt.Errorf("failed to verify Paseto V2 public token: %w", err)
	}


	fmt.Println("Verified Paseto V2 public Payload (JSON):")
	fmt.Println(toJSON(publicVerifiedPayloadV2))

}
  • Paseto V3
package main

import (
	"aidanwoods.dev/go-paseto"
	"encoding/json"
	"fmt"
	"github.com/fsobh/token"
	"log"

	"time"
)

func toJSON(data interface{}) string {
	jsonBytes, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		log.Fatalf("Failed to marshal to JSON: %v", err)
	}
	return string(jsonBytes)
}

func main() {
	
	// ** Paseto V3 Local **

	symmetricKeyV3 := paseto.NewV3SymmetricKey()
	symmetricKeyStringV3 := symmetricKeyV3.ExportHex()
	
	localMakerV3, err := token.NewPasetoV3Local(symmetricKeyStringV3)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V3 local token maker: %w", err)
	}

	localTokenStringV3, localPayloadV3, err := localMakerV3.CreateToken("bob", 24*time.Hour)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V3 local token: %w", err)
	}

	fmt.Println("Created Paseto V3 local Token (JSON):")
	fmt.Println(toJSON(map[string]interface{}{
		"token":      localTokenStringV3,
		"payload":    localPayloadV3,
		"expiration": localPayloadV3.ExpiredAt,
	}))

	localVerifiedPayloadV3, err := localMakerV3.VerifyToken(localTokenStringV3)
	if err != nil {
		_ = fmt.Errorf("failed to verify Paseto V3 local token: %w", err)
	}

	fmt.Println("Verified Paseto V3 local Payload (JSON):")
	fmt.Println(toJSON(localVerifiedPayloadV3))

	
	
	
	
	// ** Paseto V3 Public **

	privateKeyV3 := paseto.NewV3AsymmetricSecretKey()
	publicKeyV3 := privateKeyV3.Public()

	privateKeyStringV3 := privateKeyV3.ExportHex()
	publicKeyStringV3 := publicKeyV3.ExportHex()
	
	publicMakerV3, err := token.NewPasetoV3Public(privateKeyStringV3, publicKeyStringV3)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V3 public token maker: %w", err)
	}

	// Create a token
	publicTokenStringV3, publicPayloadV3, err := publicMakerV3.CreateToken("dave", 24*time.Hour)
	if err != nil {
		_ = fmt.Errorf("failed to create Paseto V3 public token: %w", err)
	}

	// Display token and payload in JSON
	fmt.Println("Created Paseto V3 public Token (JSON):")
	fmt.Println(toJSON(map[string]interface{}{
		"token":      publicTokenStringV3,
		"payload":    publicPayloadV3,
		"expiration": publicPayloadV3.ExpiredAt,
	}))

	// Verify the token
	publicVerifiedPayloadV3, err := publicMakerV3.VerifyToken(publicTokenStringV3)
	if err != nil {
		_ = fmt.Errorf("failed to verify Paseto V3 public token: %w", err)
	}

	// Display verified payload in JSON
	fmt.Println("Verified Paseto V3 public Payload (JSON):")
	fmt.Println(toJSON(publicVerifiedPayloadV3))
}
  • JWT
package main

import (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"github.com/fsobh/token"
	"golang.org/x/crypto/ed25519"
	"log"
	"time"
)

func toJSON(data interface{}) string {
	jsonBytes, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		log.Fatalf("Failed to marshal to JSON: %v", err)
	}
	return string(jsonBytes)
}

func main() {

	// ** JWT Asymmetric **
	publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		fmt.Println("error while generating keys: ", err)
		return
	}

	jwtMakerAsymmetric, err := token.NewAsymJWTMaker(privateKey, publicKey)

	if err != nil {
		_ = fmt.Errorf("Cannot create JWT jwtMakerAsymmetric: %v\n", err)
	}

	jwtTokenAsymmetric, jwtPayloadAsymmetric, err := jwtMakerAsymmetric.CreateToken("charlie", 24*time.Hour)
	if err != nil {
		_ = fmt.Errorf("failed to create token: %w", err)
	}

	fmt.Println("Created Token (JSON):")
	fmt.Println(toJSON(map[string]interface{}{
		"token":      jwtTokenAsymmetric,
		"payload":    jwtPayloadAsymmetric,
		"expiration": jwtPayloadAsymmetric.ExpiredAt,
	}))

	jwtVerifiedPayloadAsymmetric, err := jwtMakerAsymmetric.VerifyToken(jwtTokenAsymmetric)
	if err != nil {
		_ = fmt.Errorf("failed to verify token: %w", err)
	}

	fmt.Println("Verified Payload (JSON):")
	fmt.Println(toJSON(jwtVerifiedPayloadAsymmetric))





	// ** JWT Symmetric **

	symmetricKey := "abcdefghijklmnopqrstuvwxyzABCDEF"

	jwtMakerSymmetric, err := token.NewJWTMaker(symmetricKey)

	if err != nil {
		_ = fmt.Errorf("Cannot create JWT jwtMakerSymmetric: %v\n", err)
	}

	jwtTokenSymmetric, jwtPayloadSymmetric, err := jwtMakerSymmetric.CreateToken("charlie", 24*time.Hour)
	if err != nil {
		_ = fmt.Errorf("failed to create token: %w", err)
	}

	// Display token and payload in JSON
	fmt.Println("Created Token (JSON):")
	fmt.Println(toJSON(map[string]interface{}{
		"token":      jwtTokenSymmetric,
		"payload":    jwtPayloadSymmetric,
		"expiration": jwtPayloadSymmetric.ExpiredAt,
	}))

	// Verify the token
	jwtVerifiedPayloadSymmetric, err := jwtMakerSymmetric.VerifyToken(jwtTokenSymmetric)
	if err != nil {
		_ = fmt.Errorf("failed to verify token: %w", err)
	}

	// Display verified payload in JSON
	fmt.Println("Verified Payload (JSON):")
	fmt.Println(toJSON(jwtVerifiedPayloadSymmetric))
}

πŸ§ͺ Testing

Run the test suite using the following command: Using go modules Β 

❯ make test

πŸ“Œ Project Roadmap

  • Task 1: Implement JWT options.
  • Task 2: Implement Paseto V2-V3 public and local options
  • Task 3: Implement feature Paseto V4 public and local options.

πŸ”° Contributing

Contributing Guidelines
  1. Fork the Repository: Start by forking the project repository to your github account.
  2. Clone Locally: Clone the forked repository to your local machine using a git client.
    git clone https://github.com/fsobh/token
  3. Create a New Branch: Always work on a new branch, giving it a descriptive name.
    git checkout -b new-feature-x
  4. Make Your Changes: Develop and test your changes locally.
  5. Commit Your Changes: Commit with a clear message describing your updates.
    git commit -m 'Implemented new feature x.'
  6. Push to github: Push the changes to your forked repository.
    git push origin new-feature-x
  7. Submit a Pull Request: Create a PR against the original project repository. Clearly describe the changes and their motivations.
  8. Review: Once your PR is reviewed and approved, it will be merged into the main branch. Congratulations on your contribution!
Contributor Graph


πŸŽ— License

This project is protected under the MIT License. For more details, refer to the LICENSE file.


πŸ™Œ Acknowledgments


About

A Go module for seamless JWT & PASETO token integration

Resources

License

Stars

Watchers

Forks

Packages

No packages published