jot

package module
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2024 License: MIT Imports: 6 Imported by: 0

README

Version Built with GoLang License Tests Go Report Card Go Coverage

Jot

A simple package to implement generating and verifying JWT tokens. It generates and verifies both auth tokens and refresh tokens.

This module uses github.com/golang-jwt/jwt/v5 for token generation and validation. It simply adds some convenience methods for extracting a token from request headers and validating it, and for getting refresh token cookies.

I wrote this simply because I became tired of writing the same code over and over again. It is intended for my own use, but someone else might find it helpful.

Usage:

package main

import (
	"fmt"
	"github.com/tsawler/jot"
	"net/http"
	"net/http/httptest"
	"time"
)

func main() {
	// create an instance of jot
	j := jot.Auth{
		Issuer:        "example.com",
		Audience:      "example.com",
		Secret:        "verysecretkey",
		TokenExpiry:   time.Minute * 15,
		RefreshExpiry: time.Hour * 24,
		CookieDomain:  "localhost",
		CookiePath:     "/",
		CookieName:     "refresh_token",
	}

	// set up a test user
	someUser := jot.User{
		ID:        1,
		FirstName: "John",
		LastName:  "Smith",
	}

	// generate tokens
	tokenPairs, _ := j.GenerateTokenPair(&someUser)
	fmt.Println("Token:", tokenPairs.Token)
	fmt.Println("Refresh Token:", tokenPairs.RefreshToken)

	// get a refresh token cookie
	cookie := j.GetRefreshCookie(tokenPairs.RefreshToken)
	fmt.Println("Cookie expiration:", cookie.Expires.UTC())

	// assuming that you are running a web app, you'll have a handler
	// that takes a request with the Authorization header set to
	// Bearer <some token>
	// where <some token> is a JWT token

	// let's build a request/response pair to send to GetTokenFromHeaderAndVerify
	res := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/some-route", nil)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenPairs.Token))

	// call GetTokenFromHeaderAndVerify
	fmt.Println("Trying a valid token...")
	_, _, err := j.GetTokenFromHeaderAndVerify(res, req)

	// print out validation results
	if err != nil {
		fmt.Println("Invalid token:", err.Error())
	} else {
		fmt.Println("Valid token!")
	}

	// now send it an invalid token
	res = httptest.NewRecorder()
	req, _ = http.NewRequest("GET", "/some-route", nil)
	req.Header.Set("Authorization", "Bearer someinvalidtoken")

	fmt.Println("Trying an invalid token...")
	_, _, err = j.GetTokenFromHeaderAndVerify(res, req)
	if err != nil {
		fmt.Println("Invalid token:", err.Error())
	} else {
		fmt.Println("Valid token!")
	}

	// you can also get cookies with the refresh token easily...
	c := j.GetRefreshCookie(tokenPairs.RefreshToken)
	fmt.Println("Refresh cookie expiry:", c.Expires.UTC())

	// and also expired refresh cookies, to force the users's browser to
	// delete the refresh cookie:
	expiredCookie := j.GetExpiredRefreshCookie()
	fmt.Println("Expired refresh cookie expiry:", expiredCookie.Expires.UTC())

}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Auth

type Auth struct {
	Issuer        string        // Who issues the token, e.g. company.com.
	Audience      string        // Who is the token for, e.g. company.com.
	Secret        string        // A strong secret, used to sign the tokens.
	TokenExpiry   time.Duration // When does the token expire, e.g. time.Minute * 15.
	RefreshExpiry time.Duration // When does the refresh token expire, e.g. time.Hour * 24.
	CookieDomain  string        // The domain, for refresh cookies.
	CookiePath    string        // The path, for refresh cookies.
	CookieName    string        // The name of the refresh token cookie.
}

Auth is the type used to instantiate this package.

func New added in v1.1.0

func New(d string) Auth

New returns an instance of Auth, with sensible defaults where possible. Naturally, any of defaults can be overridden.

func (*Auth) GenerateTokenPair

func (j *Auth) GenerateTokenPair(user *User) (TokenPairs, error)

GenerateTokenPair takes a user of type jot.User and attempts to generate a pair of tokens for that user (jwt and refresh tokens).

func (*Auth) GetExpiredRefreshCookie added in v1.0.3

func (j *Auth) GetExpiredRefreshCookie() *http.Cookie

GetExpiredRefreshCookie is a convenience method to return a cookie suitable for forcing a user's browser to delete the existing cookie.

func (*Auth) GetRefreshCookie

func (j *Auth) GetRefreshCookie(refreshToken string) *http.Cookie

GetRefreshCookie returns a cookie containing the refresh token. Note that the cookie is http only, secure, and set to same site strict mode.

func (*Auth) GetTokenFromHeaderAndVerify

func (j *Auth) GetTokenFromHeaderAndVerify(w http.ResponseWriter, r *http.Request) (string, *Claims, error)

GetTokenFromHeaderAndVerify extracts a token from the Authorization header, verifies it, and returns the token, the claims, and error, if any.

type Claims

type Claims struct {
	jwt.RegisteredClaims
}

Claims is the type used to describe the claims in a given token.

type TokenPairs

type TokenPairs struct {
	Token        string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
}

TokenPairs is the type used to generate JSON containing the JWT token and the refresh token.

type User

type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
}

User is a generic type used to hold the minimal amount of data we require in order to issue tokens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL