- π Overview
- πΎ Features
- π Project Structure
- π Getting Started
- π Project Roadmap
- π° Contributing
- π License
- π Acknowledgments
A Go module for seamless JWT & PASETO token integration
- JWT
- PASETO V2
- PASETO V3
βββ 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
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
Before getting started with token, ensure your runtime environment meets the following requirements:
- Programming Language: Go
- Package Manager: Go modules
Install the project dependencies:
β― go get github.com/fsobh/token
- 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))
}
Run the test suite using the following command:
Using go modules
Β
β― make test
-
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.
- π¬ Join the Discussions: Share your insights, provide feedback, or ask questions.
- π Report Issues: Submit bugs found or log feature requests for the
token
project. - π‘ Submit Pull Requests: Review open PRs, and submit your own PRs.
Contributing Guidelines
- Fork the Repository: Start by forking the project repository to your github account.
- Clone Locally: Clone the forked repository to your local machine using a git client.
git clone https://github.com/fsobh/token
- Create a New Branch: Always work on a new branch, giving it a descriptive name.
git checkout -b new-feature-x
- Make Your Changes: Develop and test your changes locally.
- Commit Your Changes: Commit with a clear message describing your updates.
git commit -m 'Implemented new feature x.'
- Push to github: Push the changes to your forked repository.
git push origin new-feature-x
- Submit a Pull Request: Create a PR against the original project repository. Clearly describe the changes and their motivations.
- Review: Once your PR is reviewed and approved, it will be merged into the main branch. Congratulations on your contribution!
This project is protected under the MIT License. For more details, refer to the LICENSE file.
- aidantwoods for implementing go-paseto for the core functionality