A Rust implementation of Prefixed API Key

This library is a Rust implementation of the Prefixed API Key typescript library. Though its interface differs slightly from the typescript version, this library provides the same set of features and functionality as the typescript version.

⚠️ This library is still a work in progress.

Prefixed API Key (Seam-style)

Example key: mycompany_BRTRKFsL_51FwqftsmMDHHbJAMEXXHCgG

See discussion on Hacker News

Seam-style API Keys have many advantages:

The Format

Seam-style api keys look like this:

ignore mycompany_BRTRKFsL_51FwqftsmMDHHbJAMEXXHCgG

Let's break down each component of the API key...

ignore mycompany ..._... BRTRKFsL ..._... 51FwqftsmMDHHbJAMEXXHCgG ^ ^ ^ Prefix Short Token Long Token

Getting Started

The original Typescript implementation of Prefixed API Keys has a few technical decisions hardcoded, but this crates aims to give full control over which hashing algorithm and random number generator are used. However this adds more complexity than may be desirable, so helpers are available to make configuration relatively painless.

By installing the crate with the sha2 feature flag, you can create an almost-entirely configured PrefixedApiKeyController instance using the seam_defaults function, which configures the controller the same way as Seam's Typescript implementation.

```rust use prefixedapikey::PrefixedApiKeyController;

fn main() { // A controller using rand::rng::OsRng as the RNG source, and // sha2::Sha256 as the hashing algorithm. let builderresult = PrefixedApiKeyController::configure() .prefix("mycompany".toowned()) .seam_defaults() .finalize();

assert!(builder_result.is_ok());

let mut controller = builder_result.unwrap();

// Generate a new PrefixedApiKey
let (pak, hash) = controller.generate_key_and_hash();

// Assert that the returned key matches the hash
assert!(controller.check_hash(&pak, &hash));

// Stringify the key to be sent to the user. This creates a string from the
// PrefixedApiKey which follows the `<prefix>_<short token>_<long token>` convention
let pak_string = pak.to_string();

} ```

Using the seam_defaults() function with the sha2 feature flag is equivalent to doing the following without using the sha2 feature:

```rust use sha2::Sha256; use prefixedapikey::PrefixedApiKeyController;

fn main() { let controller = PrefixedApiKeyController::<_, Sha256>::configure() .prefix("mycompany".toowned()) .rngosrng() .shorttokenlength(8) .longtokenlength(24) .finalize(); } ```