jwtoken 0.1.2

A flexible utility library for encoding and decoding JSON Web Tokens (JWT).
Documentation
jwtoken-0.1.2 has been yanked.

jwtoken

A flexible utility library for encoding and decoding JSON Web Tokens (JWT).

Installation

Add jwtoken to your Cargo.toml:

[dependencies]
# Basic usage
jwtoken = "0.1.2"

# With key generation utilities (for random secrets, RSA keypairs)
jwtoken = { version = "0.1.2", features = ["key-gen"] }

# Enable HS256 algorithm
jwtoken = { version = "0.1.2", features = ["hs256"] }

# Enable RS256 algorithm
jwtoken = { version = "0.1.2", features = ["rs256"] }

# Enable all features
jwtoken = { version = "0.1.2", features = ["full"] }

Usage

HMAC-SHA256 (HS256)

HS256 uses a shared secret key for both signing and verification:

use jwtoken::{random_secret, Jwt, Encoder, Decoded, HS256};

fn main() -> Result<(), jwtoken::JwtError> {
    // Requires the "key-gen" feature
    let secret = random_secret();
    let algorithm = HS256::new(&secret);

    // Encoding a JWT
    let token = Jwt::<Encoder>::new()
        .claim("sub", "1234567890")
        .claim("name", "John Doe")
        .claim("iat", 1516239022)
        .encode(&algorithm)?;

    println!("Generated token: {}", token);

    // Decoding and verifying the same JWT
    let decoded = Jwt::<Decoded>::decode(&token, &algorithm)?;
    println!("Decoded claims: {:?}", decoded.claims);

    Ok(())
}

RS256 (RSA-SHA256)

RS256 uses an RSA key pair, with the private key for signing and the public key for verification:

use jwtoken::{rsa_keypair, RS256Signer, RS256Verifier, Jwt, Encoder, Decoded};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Requires the "key-gen" and "rs256" features
    let (private_key, public_key) = rsa_keypair()?;

    // Create a signer with the private key
    let signer = RS256Signer::new(private_key);
    // Create a verifier with the public key
    let verifier = RS256Verifier::new(public_key);

    // Encoding a JWT
    let token = Jwt::<Encoder>::new()
        .claim("sub", "user-id-42")
        .claim("name", "Jane Doe")
        .claim("admin", true)
        .encode(&signer)?;

    println!("Generated RS256 token: {}", token);

    // Decoding and verifying the same JWT with the public key
    let decoded = Jwt::<Decoded>::decode(&token, &verifier)?;
    println!("Decoded RS256 claims: {:?}", decoded.claims);

    // The signer also implements Verifier, so it can be used for verification too
    let decoded_with_signer = Jwt::<Decoded>::decode(&token, &signer)?;
    assert_eq!(decoded.claims, decoded_with_signer.claims);

    Ok(())
}

API Reference

JWT Encoder

let jwt = Jwt::<Encoder>::new()
    .claim("key", "value")                              // Add a plain value
    .claim_json("metadata", serde_json::json!({ "role": "admin" }))  // Add a JSON value
    .encode(&algorithm)?;                               // Sign and encode to string

JWT Decoder

let decoded = Jwt::<Decoded>::decode(&token, &algorithm)?;

// Access claims
let user_id = decoded.claim("sub");
let name = decoded.claim("name");

// Access headers
let algorithm = decoded.header("alg");

Algorithms

HS256 (HMAC-SHA256)

use jwtoken::HS256;
let algorithm = HS256::new(secret_bytes);

RS256 (RSA-SHA256)

use jwtoken::{rsa_keypair, RS256Signer, RS256Verifier};

// Requires the "key-gen" and "rs256" features
let (private_key, public_key) = rsa_keypair().unwrap();

// For signing
let signer = RS256Signer::new(private_key);

// For verifying
let verifier = RS256Verifier::new(public_key);

Error Handling

The library uses a custom JwtError enum for error handling:

use jwtoken::JwtError;

match result {
    Ok(token) => println!("Success: {}", token),
    Err(JwtError::InvalidSignature) => println!("Invalid signature"),
    Err(JwtError::InvalidFormat) => println!("Malformed JWT"),
    Err(JwtError::InvalidAlgorithm) => println!("Algorithm mismatch"),
    Err(JwtError::SerializationError) => println!("JSON error"),
    Err(JwtError::Custom(msg)) => println!("Custom error: {}", msg),
}