### Install Webtokens via Nimble Source: https://context7.com/openpeeps/webtokens/llms.txt The standard command to install the webtokens package into your Nim environment. ```shell nimble install webtokens ``` -------------------------------- ### Complete JWT Authentication Flow Example Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates a full JWT authentication flow in Nim, including key generation, token creation with custom claims, and token verification with leeway for clock skew. It uses the JwtBuilder and JwtChecker APIs. ```nim import std/[times, json] import webtokens # Setup: Generate keys (in production, load from secure storage) let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let signingKey = jwkSet.findByKid("hmac-key-0") let alg = parseAlg("HS256") # === Token Creation (Login) === proc createAuthToken(userId: string, roles: seq[string]): string = var builder = newJwtBuilder() builder.setKey(alg, signingKey) # Headers builder.setHeader("typ", "JWT") builder.setHeader("kid", signingKey.itemKid()) # Standard claims builder.setIss("auth.example.com") builder.setSub(userId) builder.setAud("api.example.com") builder.setExpIn(3600) # 1 hour builder.setIat() # Custom claims builder["roles"] = %*roles builder["token_type"] = "access" result = builder.generate() # === Token Verification (Protected Routes) === proc verifyAuthToken(token: string): tuple[valid: bool, userId: string, roles: seq[string]] = var checker = newJwtChecker() checker.setKey(alg, signingKey) checker.setLeeway(JWT_CLAIM_EXP, 30) # 30-second clock skew tolerance try: discard checker.verify(token) let userId = checker.sub() var roles: seq[string] = @[] let rolesNode = checker.fromPayload("roles") if rolesNode != nil: for role in rolesNode: roles.add(role.getStr()) result = (valid: true, userId: userId, roles: roles) except JwtError as e: echo "Token verification failed: ", e.msg result = (valid: false, userId: "", roles: @[]) # === Usage === let token = createAuthToken("user-12345", @["admin", "editor"]) echo "Generated token: ", token let (valid, userId, roles) = verifyAuthToken(token) if valid: echo "Authenticated user: ", userId echo "Roles: ", roles else: echo "Authentication failed" ``` -------------------------------- ### JWT and JWK Error Handling in Webtokens Source: https://context7.com/openpeeps/webtokens/llms.txt Illustrates how to handle errors using custom exception types in the Webtokens library. It shows catching JwkError for JWK operations (e.g., file loading) and JwtError for JWT builder and verification operations. Examples include missing keys or invalid token formats. ```nim import webtokens # Handle JWK errors try: let jwkSet = loadJwkSetFromFile("/nonexistent/path.json") except JwkError as e: echo "JWK Error: ", e.msg # Handle JWT builder errors try: var builder = newJwtBuilder() # Missing key - will fail on generate let token = builder.generate() except JwtError as e: echo "JWT Error: ", e.msg # Handle verification errors try: var checker = newJwtChecker() # Verification without proper setup will fail discard checker.verify("invalid.token.here") except JwtError as e: echo "Verification failed: ", e.msg ``` -------------------------------- ### Configure Crypto Provider for LibJWT Source: https://context7.com/openpeeps/webtokens/llms.txt Configures the cryptographic provider for the LibJWT library. Supports OpenSSL, GnuTLS, and mbedTLS. You can get the current provider's name and enum value, or set a new provider by its name (string) or enum value. Errors during provider setting are caught as JwtError. ```nim import webtokens # Get current crypto provider echo "Current provider: ", currentCryptoProviderName() echo "Provider enum: ", currentCryptoProvider() # Set crypto provider by name try: setCryptoProvider("openssl") except JwtError as e: echo "Failed to set provider: ", e.msg # Set crypto provider by enum try: setCryptoProvider(JWT_CRYPTO_OPS_OPENSSL) except JwtError as e: echo "Failed to set provider: ", e.msg ``` -------------------------------- ### Build and Sign JWTs in Nim Source: https://context7.com/openpeeps/webtokens/llms.txt Shows how to initialize a JwtBuilder, set standard claims like issuer, subject, and expiration, and generate a signed token. ```Nim import std/[times, json] import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.findByKid("hmac-key-0") var builder = newJwtBuilder() builder.setKey(parseAlg("HS256"), key) builder.setHeader("typ", "JWT") builder.setHeader("kid", key.itemKid()) builder.setIss("my-application") builder.setSub("user-12345") builder.setAud("api.example.com") builder.setExpIn(3600) builder.setIat() builder.setNbf(getTime()) builder.setJti("unique-token-id") let token = builder.generate() echo "JWT: ", token ``` -------------------------------- ### Create JWT Verifier and Verify Token (Nim) Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates how to create a JwtChecker instance to verify JWT tokens. It includes setting the verification key, generating a token, and then using the checker to validate the token and extract standard claims like issuer and subject. ```nim import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.findByKid("hmac-key-0") # First, create a token var builder = newJwtBuilder() builder.setKey(parseAlg("HS256"), key) builder.setIss("my-app") builder.setSub("user123") builder.setExpIn(3600) let token = builder.generate() # Create verifier var checker = newJwtChecker() checker.setKey(parseAlg("HS256"), key) # Verify the token (throws JwtError on failure) if checker.verify(token): echo "Token verified successfully!" # Extract standard claims echo "Issuer: ", checker.iss() echo "Subject: ", checker.sub() echo "Audience: ", checker.aud() echo "JWT ID: ", checker.jti() ``` -------------------------------- ### Create and Sign JWT with HMAC SHA-256 in Nim Source: https://github.com/openpeeps/webtokens/blob/main/README.md Demonstrates how to create and sign a JSON Web Token (JWT) using the HMAC SHA-256 algorithm with the 'webtokens' Nim package. It involves generating a JWK Set, loading a key, setting token claims and headers, and then generating and verifying the token. ```nim {.passL:"-L/opt/local/lib -ljwt", passC:"-I /opt/local/include".} import std/[times, json] import webtokens # Generate a JWK Set with one random HMAC (oct) key let jwksJson = generateJwkSet(1, 32) let set = loadJwkSetFromJson($jwksJson) let key = set.findByKid("hmac-key-0") let alg = parseAlg("HS256") # Initialize JWT Builder var builder = newJwtBuilder() builder.setKey(alg, key) builder.setHeader("typ", "JWT") builder.setHeader("kid", key.itemKid()) builder.setIss("example-app") builder.setSub("user123") builder.setExpIn(3600) # token expires in 1 hour # Generate the token let token = builder.generate() echo "Generated JWT: ", token # Now, you can use this token for authentication/authorization var verifier = newJwtChecker() verifier.setKey(alg, key) verifier.setLeeway(JWT_CLAIM_EXP, 5) # small clock skew if verifier.verify(token): echo "Verified OK!" ``` -------------------------------- ### Manage JWK Sets Source: https://context7.com/openpeeps/webtokens/llms.txt Provides methods to generate, load, and query JWK sets from various sources including JSON strings, files, and remote URLs. ```nim # Generate a JWK Set let jwkSet = generateJwkSet(count = 3, keyLen = 32) # Load from JSON let jwkSetFromJson = loadJwkSetFromJson($jwksJson) # Load from File let jwkSetFromFile = loadJwkSetFromFile("/path/to/jwks.json") # Load from URL let jwkSetFromUrl = loadJwkSetFromUrl("https://example.com/.well-known/jwks.json", verifyTls = true) ``` -------------------------------- ### Manage Time-based JWT Settings in Nim Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates how to toggle automatic 'iat' claim generation and apply time offsets to specific claims. ```Nim import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.itemByIndex(0) var builder = newJwtBuilder() builder.setKey(parseAlg("HS256"), key) builder.enableIat(true) builder.timeOffset(JWT_CLAIM_EXP, 60) let token = builder.generate() ``` -------------------------------- ### newJwtChecker - Create JWT Verifier Source: https://context7.com/openpeeps/webtokens/llms.txt Initializes a new JwtChecker instance to validate JWT signatures and extract claims from tokens. ```APIDOC ## newJwtChecker ### Description Creates a new JwtChecker instance for verifying JWT tokens and extracting claims. The checker validates the token signature and can verify time-based claims. ### Method N/A (Library Function) ### Parameters - **key** (Jwk) - Required - The cryptographic key used for signature verification. ### Response - **checker** (JwtChecker) - An instance of the verifier configured with the provided key. ### Example ```nim var checker = newJwtChecker() checker.setKey(parseAlg("HS256"), key) if checker.verify(token): echo "Token verified successfully!" ``` ``` -------------------------------- ### Parse JWT Algorithms Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates how to map string identifiers to the library's internal algorithm enum types and convert them back to strings. ```nim import webtokens # HMAC algorithms let hs256 = parseAlg("HS256") # JWT_ALG_HS256 let hs384 = parseAlg("HS384") # JWT_ALG_HS384 let hs512 = parseAlg("HS512") # JWT_ALG_HS512 # RSA algorithms let rs256 = parseAlg("RS256") # JWT_ALG_RS256 let rs384 = parseAlg("RS384") # JWT_ALG_RS384 let rs512 = parseAlg("RS512") # JWT_ALG_RS512 # ECDSA algorithms let es256 = parseAlg("ES256") # JWT_ALG_ES256 let es384 = parseAlg("ES384") # JWT_ALG_ES384 let es512 = parseAlg("ES512") # JWT_ALG_ES512 # Other algorithms let ps256 = parseAlg("PS256") # JWT_ALG_PS256 (RSA-PSS) let eddsa = parseAlg("EDDSA") # JWT_ALG_EDDSA (EdDSA) # Convert algorithm back to string echo $hs256 # Output: "HS256" ``` -------------------------------- ### Query JWK Items Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates how to retrieve specific keys from a JWK set using their unique identifier (kid) or by index. ```nim import std/json import webtokens let jwksJson = generateJwkSet(3, 32) let jwkSet = loadJwkSetFromJson($jwksJson) # Find specific key by kid let key = jwkSet.findByKid("hmac-key-1") echo "Found key: ", key.itemKid() echo "Algorithm: ", key.itemAlg() echo "Key type: ", key.itemKeyType() echo "Is private: ", key.isPrivate() ``` -------------------------------- ### setLeeway - Configure Time Tolerance Source: https://context7.com/openpeeps/webtokens/llms.txt Configures the time tolerance (leeway) for verifying claims like expiration, not-before, and issued-at to handle clock skew. ```APIDOC ## setLeeway ### Description Sets leeway (in seconds) for time-based claim verification to account for clock skew between systems. ### Parameters - **claimType** (string) - Required - The JWT claim type (e.g., JWT_CLAIM_EXP, JWT_CLAIM_NBF). - **seconds** (int) - Required - The number of seconds to allow as tolerance. ### Example ```nim checker.setLeeway(JWT_CLAIM_EXP, 5) ``` ``` -------------------------------- ### Access JWK Item Properties in Nim Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates how to retrieve keys from a JWK set by index and access their metadata such as algorithm, key type, usage, and raw key material. ```Nim import std/json import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.itemByIndex(0) echo "Kid: ", key.itemKid() echo "Algorithm: ", key.itemAlg() echo "Key Type: ", key.itemKeyType() echo "Key Use: ", key.itemUse() echo "Is Private: ", key.isPrivate() echo "Curve: ", key.itemCurve() echo "PEM: ", key.itemPem() let octBytes: seq[byte] = key.itemOctKey() echo "Key length: ", octBytes.len, " bytes" ``` -------------------------------- ### High-Level JWS API - Sign JWT (Nim) Source: https://context7.com/openpeeps/webtokens/llms.txt Demonstrates the high-level JWS API for signing JWTs. It simplifies the process by using JwsHeader and JwsOptions to define the algorithm, key, claims, and other signing parameters like issued-at and expiration time. ```nim import std/json import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) # Define header with algorithm and key id let header = JwsHeader( alg: "HS256", kid: "hmac-key-0", typ: "JWT" ) # Define claims as JSON let claims = %*{ "sub": "user-789", "iss": "auth-server", "roles": ["admin", "user"] } # Configure options let options = JwsOptions( iat: true, # Include issued-at claim expIn: 7200, # Expire in 2 hours leeway: 0 ) # Sign and generate token let token = sign(jwkSet, header, claims, options) echo "Signed JWT: ", token ``` -------------------------------- ### Configure Custom Claims and Headers in Nim Source: https://context7.com/openpeeps/webtokens/llms.txt Explains how to add custom claims and headers to a JWT, supporting various data types including strings, integers, booleans, and JSON objects. ```Nim import std/json import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.itemByIndex(0) var builder = newJwtBuilder() builder.setKey(parseAlg("HS256"), key) builder.setClaim("username", "johndoe") builder["email"] = "john@example.com" builder["roles"] = %*["admin", "user"] builder.setHeader("custom_string", "value") builder.setHeaderJson("custom_json", %*{"nested": "value"}) let token = builder.generate() ``` -------------------------------- ### High-Level JWS API - sign Source: https://context7.com/openpeeps/webtokens/llms.txt Provides a simplified interface for signing JWTs using JwsHeader, claims, and JwsOptions. ```APIDOC ## sign ### Description The high-level JWS API provides a simplified interface for signing JWTs using JwsHeader and JwsOptions. ### Parameters - **jwkSet** (JwkSet) - Required - The set of keys for signing. - **header** (JwsHeader) - Required - The JWT header containing algorithm and key ID. - **claims** (JsonNode) - Required - The claims to include in the token. - **options** (JwsOptions) - Optional - Configuration for iat, expIn, and leeway. ### Response - **string** - The signed JWT string. ``` -------------------------------- ### Configure Time Tolerance for JWT Claims (Nim) Source: https://context7.com/openpeeps/webtokens/llms.txt Explains how to set a 'leeway' or tolerance in seconds for time-based JWT claim verification. This accounts for clock skew between systems, ensuring tokens are considered valid within a small time window around their expiration or not-before times. ```nim import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.itemByIndex(0) var checker = newJwtChecker() checker.setKey(parseAlg("HS256"), key) # Set 5-second leeway for expiration check checker.setLeeway(JWT_CLAIM_EXP, 5) # Set leeway for other time claims checker.setLeeway(JWT_CLAIM_NBF, 5) # not-before checker.setLeeway(JWT_CLAIM_IAT, 5) # issued-at # Token verification will now tolerate 5 seconds of clock skew ``` -------------------------------- ### High-Level JWS API - Verify JWT (Nim) Source: https://context7.com/openpeeps/webtokens/llms.txt Illustrates how to use the high-level verify function from the JWS API to validate a JWT. It takes a JwkSet and the token, and optionally JwsOptions for verification parameters like leeway, returning the parsed payload. ```nim import std/json import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) # Create a token first let header = JwsHeader(alg: "HS256", kid: "hmac-key-0", typ: "JWT") let claims = %*{"sub": "user-abc", "data": "important"} let token = sign(jwkSet, header, claims) # Verify with options let verifyOptions = JwsOptions( leeway: 10 # 10-second tolerance for time claims ) # The verify function would be called here, e.g.: # let verifiedClaims = verify(jwkSet, token, verifyOptions) # echo verifiedClaims.pretty() ``` -------------------------------- ### Generate HMAC JWK Source: https://context7.com/openpeeps/webtokens/llms.txt Creates a symmetric JSON Web Key for HMAC algorithms with a specified key identifier and length. ```nim import std/json import webtokens # Generate a single HMAC JWK with custom parameters let jwk = generateOctJwk( kid = "my-signing-key", # Key identifier alg = "HS256", # Algorithm keyLen = 32 # Key length in bytes (256 bits) ) echo jwk.pretty() ``` -------------------------------- ### Set Time Offsets for JWT Claims Source: https://context7.com/openpeeps/webtokens/llms.txt Adjusts time-based claims like 'issued at' (iat) and 'not before' (nbf) by a specified offset in seconds. This is useful for setting claims relative to the current time during token generation. ```nim import webtokens builder.timeOffset(JWT_CLAIM_IAT, -30) # 30 seconds in the past builder.timeOffset(JWT_CLAIM_NBF, 0) let token = builder.generate() ``` -------------------------------- ### Extract Claims from Verified JWT (Nim) Source: https://context7.com/openpeeps/webtokens/llms.txt Shows how to extract various claims from a JWT after it has been successfully verified. It covers standard claims, time-based claims converted to Nim's Time type, and custom claims accessed directly from the payload. ```nim import std/[times, json] import webtokens let jwksJson = generateJwkSet(1, 32) let jwkSet = loadJwkSetFromJson($jwksJson) let key = jwkSet.itemByIndex(0) # Create token with various claims var builder = newJwtBuilder() builder.setKey(parseAlg("HS256"), key) builder.setIss("auth-service") builder.setSub("user-456") builder.setExpIn(3600) builder["custom_claim"] = "custom_value" builder["user_data"] = %*{"name": "John", "age": 30} let token = builder.generate() # Verify and extract claims var checker = newJwtChecker() checker.setKey(parseAlg("HS256"), key) discard checker.verify(token) # Standard claim helpers echo "Issuer: ", checker.iss() echo "Subject: ", checker.sub() # Get time claims as Time objects let expTime: Time = checker.claimTime(JWT_CLAIM_EXP) let iatTime: Time = checker.claimTime(JWT_CLAIM_IAT) echo "Expires: ", expTime echo "Issued at: ", iatTime # Get claim by type let issValue = checker.getClaim(JWT_CLAIM_ISS) echo "ISS via getClaim: ", issValue # Access custom claims via cached payload let customValue = checker.fromPayload("custom_claim") echo "Custom claim: ", customValue let userData = checker.fromPayload("user_data") echo "User name: ", userData["name"].getStr() ``` -------------------------------- ### Verify JWT Payload and Extract Claims Source: https://context7.com/openpeeps/webtokens/llms.txt Verifies a JWT token using a JWK set, header, token string, and options. On success, it returns the payload as a JsonNode, allowing extraction of claims like 'sub' (subject) and 'data'. Throws a JwtError on failure. ```nim import webtokens let payload: JsonNode = verify(jwkSet, header, token, verifyOptions) echo "Subject: ", payload["sub"].getStr() echo "Data: ", payload["data"].getStr() ``` -------------------------------- ### Parse JWT Payload Without Verification (Nim) Source: https://context7.com/openpeeps/webtokens/llms.txt Provides a function to parse the payload of a JWT without verifying its signature. This is useful for inspecting token contents but should be used with caution as it bypasses security checks. ```nim import std/json import webtokens let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaXNzIjoibXktYXBwIn0.signature" # Parse payload without verification (UNSAFE - only for inspection) let payload: JsonNode = parsePayloadJson(token) echo payload.pretty() # Output: # { # "sub": "user123", # "iss": "my-app" # } ``` -------------------------------- ### parsePayloadJson - Parse JWT Payload Without Verification Source: https://context7.com/openpeeps/webtokens/llms.txt Decodes and parses the payload from a JWT without performing signature verification. Intended for inspection purposes only. ```APIDOC ## parsePayloadJson ### Description Decodes and parses the payload from a JWT without verifying the signature. Useful for inspecting tokens or when verification is handled separately. ### Parameters - **token** (string) - Required - The raw JWT string. ### Response - **JsonNode** - The parsed JSON payload of the token. ### Example ```nim let payload = parsePayloadJson(token) echo payload.pretty() ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.