keymaker

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2023 License: MIT Imports: 5 Imported by: 0

README

keymaker

Overview

Keymaker is a zero-dependency Golang package that makes it easy to generate API keys in your application.

This package was inspired by an excellent YouTube video done by Josh Twist (CEO & Co-founder at zuplo) titled API Key Authentication Best Practices

Installation

go get github.com/williepotgieter/keymaker

API Key format

The package generates API keys in the following standardized format:

<LABEL>_<SECRET>_<CHECKSUM>
Label

Labelling API keys is a convenient way to make keys easily identifiable between differen environments or purpose. Labels can be any string.

Examples
  • skp => shareable key production
  • pks => publishable key staging
Secret

Secrets are random strings made up of characters a-z, A-Z and 0-9. They are automatically generated by the package using Golang's built-in rand/crypto package and a Fisher-Yates shuffling algorithm. The length of the secret can be adjusted as required, but can be maximum 256 charaters.

Examples
  • 15nd14iju19qV3s63379a5iJz1jGunI => 32 characters
  • Kl1kD9mj7ZU742K399Sr03Uo5Acb21Gu8I3Y2c13e23Eko4B7ew1zZy10207Pm02 => 64 characters
Checksum

The checksum is the computed CRC-32 checksum of the generated key, using Golang's built-in hash/crc32 package.

Examples
  • 995215320 => 32 character secret
  • 1215000562 => 64 character secret
What will the generated keys look like?
Example 1

skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320

Example 2

pks_Kl1kD9mj7ZU742K399Sr03Uo5Acb21Gu8I3Y2c13e23Eko4B7ew1zZy10207Pm02_1215000562

Generating API keys

API Keys are generated by the NewApiKey function. The following code will generate an API key with a label of skp and a secret with a length of 32 characters.

key, err := keymaker.NewApiKey("skp", 32)

The code above will return a ApiKey struct or an error wrapped in ErrGenerateNewApiKey if there was an error during creation.

type ApiKey struct {
	Label    string
	Secret   string
	Checksum uint32
}

Once an API key has been created it can be converted into a string using the String() function

key, _ := keymaker.NewApiKey("skp", 32)
// Output:
//  ApiKey{
//      Label:      "skp",
//      Secret:     "15nd14iju19qV3s63379a5iJz1jGunI",
//      Checksum:   995215320,
//  }

apiKeyStr := key.String()
// Output: skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320

Parsing API keys

Valid API key strings in the format <LABEL>_<SECRET>_<CHECKSUM> can be parsed into ApiKey structs using the ParseApiKey function.

apiKey, err := ParseApiKey("skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320")
// Output:
//  ApiKey{
//      Label:      "skp",
//      Secret:     "15nd14iju19qV3s63379a5iJz1jGunI",
//      Checksum:   995215320,
//  }

Validating API keys

Use the ValidateApiKey function to check wheter a string value API key is valid. This function can be integrated with http request handling middleware to quickly (and inexpensively) filter out any invalid API keys early on.

validA, err := ValidateApiKey("skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320")
// Output: valid = true, err = nil

validB, err := ValidateApiKey("skp_15nd14iju19qV3s63379a5iJz1jGunI_123456789")
// Output: valid = false, err = nil

Errors

If any keymaker functions generate an error, they will always be wrapped in one of the following errors:

var (
	ErrInvalidApiKey     = errors.New("invalid api key")
	ErrGenerateNewApiKey = errors.New("error while generating new api key")
	ErrParseApiKey       = errors.New("error while parsing api key")
	ErrValidateApiKey    = errors.New("error while validating api key")
)

References

Twist, J. (2022). API Key Authentication Best Practices. Zuplo. Available at: https://www.youtube.com/watch?v=ooyOmiczY1g [Accessed 28 Nov. 2023].

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidApiKey     = errors.New("invalid api key")
	ErrGenerateNewApiKey = errors.New("error while generating new api key")
	ErrParseApiKey       = errors.New("error while parsing api key")
	ErrValidateApiKey    = errors.New("error while validating api key")
)

Functions

This section is empty.

Types

type ApiKey

type ApiKey struct {
	Label    string
	Secret   string
	Checksum uint32
}

func NewApiKey

func NewApiKey(label string, length uint8) (ApiKey, error)

NewApiKey generates a new API key in the format <LABEL>_<SECRET>_<CHECKSUM> Example: skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320 The length (number of characters) of the secret can be set by the 'length' argument. Although highly unlikely, it will return the error wrapped with "ErrGenerateNewApiKey" if there was a problem during the creation of the key.

func ParseApiKey

func ParseApiKey(key string) (ApiKey, error)

ParseApiKey converts an API key string to an API struct if the string is a valid API key. Parsing errors will be wrapped by either "ErrValidateApiKey" or "ErrInvalidApiKey".

func (ApiKey) String

func (k ApiKey) String() string

String returns the string value of the API key in the format <LABEL>_<SECRET>_<CHECKSUM> eg. skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320

func (ApiKey) ValidateApiKey

func (k ApiKey) ValidateApiKey(key string) (bool, error)

ValidateApiKey validates a given API key by checking that it is of the correct form <LABEL>_<SECRET>_<CHECKSUM> and that the checksum is valid. This function can be integrated into http routing middleware to quickly validate API keys from incomming requests and reject invalid API keys as early as possible.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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