### Sample Validation Options Usage Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Illustrates the usage of legacy validation options for JWT verification. This example shows how to specify lifetime grace period, whether to require the expiration claim, and a list of valid issuers. ```lua local jwt_obj = jwt:verify(key, jwt_token, { lifetime_grace_period = 120, require_exp_claim = true, valid_issuers = { "my-trusted-issuer", "my-other-trusteed-issuer" } } ) ``` -------------------------------- ### Luarocks Installation Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Command to install the lua-resty-jwt library using the Luarocks package manager. ```bash luarocks install lua-resty-jwt ``` -------------------------------- ### RSA Key Operations with EVP Module in Lua Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt This example shows how to perform RSA signing and certificate operations using the resty.evp module for lower-level cryptographic control. It covers creating an RSA signer from a private key, signing a message, and verifying a certificate. It requires the resty.evp library. ```lua local evp = require "resty.evp" -- Create an RSA signer from private key local private_key_pem = [[ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA2mKqH... -----END RSA PRIVATE KEY----- ]] local signer, err = evp.RSASigner:new(private_key_pem) if not signer then ngx.say("Signer creation failed: ", err) return end -- Sign a message local message = "header.payload" local signature, err = signer:sign(message, evp.CONST.SHA256_DIGEST) if not signature then ngx.say("Signing failed: ", err) return end -- Create certificate object from PEM local cert_pem = [[ -----BEGIN CERTIFICATE----- MIIBkTCB... -----END CERTIFICATE----- ]] local cert, err = evp.Cert:new(cert_pem) if cert then -- Get certificate fingerprint local fingerprint = cert:get_fingerprint("SHA256") ngx.say("Cert fingerprint: ", fingerprint) -- Output: "A1:B2:C3:D4:E5:F6:..." -- Verify certificate against trusted CAs local trusted, err = cert:verify_trust("/etc/nginx/certs/ca-bundle.crt") if trusted then ngx.say("Certificate is trusted") end end -- Create RSA verifier from certificate local verifier, err = evp.RSAVerifier:new(cert) local is_valid, err = verifier:verify(message, signature, evp.CONST.SHA256_DIGEST) gx.say("Signature valid: ", is_valid) ``` -------------------------------- ### Nginx Configuration for Lua Package Path Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Example Nginx configuration snippet to set the `lua_package_path` directive, allowing ngx_lua to find the lua-resty-jwt library. ```nginx # nginx.conf http { lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;"; ... } ``` -------------------------------- ### JWT Auth with Key ID and Redis (Nginx Config) Source: https://github.com/skylothar/lua-resty-jwt/blob/master/examples/README.md This Nginx configuration demonstrates JWT authentication where keys are managed using Redis. It specifies Redis host and port, and utilizes a Lua script (redjwt.lua) for authentication, allowing for dynamic key rotation and management. ```nginx location / { set $redhost "127.0.0.1"; set $redport 6379; # set $reddb 1; # set $redauth "your-redis-pass"; access_by_lua_file /etc/nginx/lua/redjwt.lua; echo "i am protected jwt guard"; } ``` -------------------------------- ### Nginx JWT Access Guard with Lua Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt This example demonstrates how to protect nginx locations using JWT authentication. It retrieves the JWT from query parameters or cookies, verifies it using a secret, and sets upstream request headers with user information. It requires the resty.jwt library. ```lua -- /etc/nginx/lua/guard.lua local jwt = require "resty.jwt" -- Get token from query param or cookie local jwt_token = ngx.var.arg_jwt if jwt_token then -- Store in cookie for subsequent requests ngx.header["Set-Cookie"] = "jwt=" .. jwt_token .. "; Path=/; HttpOnly" else jwt_token = ngx.var.cookie_jwt end if not jwt_token then ngx.status = ngx.HTTP_UNAUTHORIZED ngx.say("Missing JWT token") ngx.exit(ngx.HTTP_OK) end -- Verify the token local jwt_obj = jwt:verify(ngx.var.jwt_secret, jwt_token) if not jwt_obj.verified then ngx.status = ngx.HTTP_UNAUTHORIZED ngx.header["WWW-Authenticate"] = 'Bearer error="invalid_token"' ngx.say(jwt_obj.reason) ngx.exit(ngx.HTTP_OK) end -- Set user info for upstream gx.req.set_header("X-User-ID", jwt_obj.payload.sub) gx.req.set_header("X-User-Role", jwt_obj.payload.role or "user") -- nginx.conf configuration: -- location /api { -- set $jwt_secret "your-256-bit-secret"; -- access_by_lua_file /etc/nginx/lua/guard.lua; -- proxy_pass http://upstream; -- } ``` -------------------------------- ### JWT Auth with Query and Cookie (Nginx Config) Source: https://github.com/skylothar/lua-resty-jwt/blob/master/examples/README.md This Nginx configuration protects a location using JWT authentication. It sets a JWT secret and uses a Lua script (guard.lua) to perform the access control. The protected resource returns a message if authentication is successful. ```nginx location / { access_log off; default_type text/plain; set $jwt_secret "your-own-jwt-secret"; access_by_lua_file /etc/nginx/lua/guard.lua; echo "i am protected by jwt guard"; } ``` -------------------------------- ### Sample Claim Specification with Validators Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Demonstrates how to define a claim specification using various validators from the resty.jwt-validators library. This includes optional matching, equality checks, and required claims. ```lua local validators = require "resty.jwt-validators" local claim_spec = { sub = validators.opt_matches("^[a-z]+$"), iss = validators.equals_any_of({ "first", "second" }), __jwt = validators.require_one_of({ "foo", "bar" }) } ``` -------------------------------- ### Dynamic Key Lookup with Lua-Resty-JWT Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Demonstrates how to use a function for dynamic key lookup based on the JWT's 'kid' header. This is useful for key rotation and multi-tenant authentication. It requires the resty.redis library for fetching keys from Redis. ```lua local jwt = require "resty.jwt" local redis = require "resty.redis" -- Define a key lookup function local function get_key_by_kid(kid) local red = redis:new() red:set_timeout(100) local ok, err = red:connect("127.0.0.1", 6379) if not ok then ngx.log(ngx.ERR, "Redis connection failed: ", err) return nil -- Returning nil causes verification to fail end local key, err = red:get("jwt_keys:" .. kid) if not key or key == ngx.null then ngx.log(ngx.ERR, "Key not found for kid: ", kid) return nil end red:set_keepalive(10000, 100) return key end -- Verify using the function (only works with HS256/HS512) local jwt_obj = jwt:verify(get_key_by_kid, jwt_token) if jwt_obj.verified then ngx.say("Authenticated user: ", jwt_obj.payload.sub) else ngx.status = ngx.HTTP_UNAUTHORIZED ngx.say("Auth failed: ", jwt_obj.reason) end ``` -------------------------------- ### Docker Test Script Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Command to execute the testing script for lua-resty-jwt using Docker. ```bash ./ci script ``` -------------------------------- ### Nginx Configuration for JWT Verification and Signing Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This snippet demonstrates how to configure Nginx to handle JWT verification and signing using the lua-resty-jwt library. It requires setting the lua_package_path and defines two locations, '/verify' and '/sign', each with its own Lua script. ```nginx # nginx.conf: lua_package_path "/path/to/lua-resty-jwt/lib/?.lua ਉਸ;"; server { default_type text/plain; location = /verify { content_by_lua ' local cjson = require "cjson" local jwt = require "resty.jwt" local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" .. ".eyJmb28iOiJiYXIifQ" .. ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY" local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token) ngx.say(cjson.encode(jwt_obj)) '; } location = /sign { content_by_lua ' local cjson = require "cjson" local jwt = require "resty.jwt" local jwt_token = jwt:sign( "lua-resty-jwt", { header={typ="JWT", alg="HS256"}, payload={foo="bar"} } ) ngx.say(jwt_token) '; } } ``` -------------------------------- ### Sample Custom Claim Specification Table Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Illustrates how to define a `claim_spec` table for JWT verification. This table contains claim names as keys and validator functions as values. It demonstrates validation for 'sub', 'iss', and a special '__jwt' claim for validating the entire JWT object. ```lua { sub = function(val) return string.match("^[a-z]+$", val) end, iss = function(val) for _, value in pairs({ "first", "second" }) do if value == val then return true end end return false end, __jwt = function(val, claim, jwt_json) if val.payload.foo == nil or val.payload.bar == nil then error("Need to specify either 'foo' or 'bar'") end end } ``` -------------------------------- ### Load and Verify JWT Separately with Dynamic Key Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Loads and parses a JWT without immediate verification, allowing inspection of headers (like 'kid') to determine the appropriate key for subsequent verification. This is useful for multi-tenant systems. Dependencies include resty.jwt. ```lua local jwt = require "resty.jwt" local jwt_token = ngx.var.arg_jwt -- Step 1: Load and parse the JWT without verification local jwt_obj = jwt:load_jwt(jwt_token) if not jwt_obj.valid then ngx.status = ngx.HTTP_BAD_REQUEST ngx.say("Invalid JWT format: ", jwt_obj.reason) ngx.exit(ngx.HTTP_OK) end -- Inspect header to determine which key to use local kid = jwt_obj.header.kid local alg = jwt_obj.header.alg ngx.say("Key ID: ", kid) ngx.say("Algorithm: ", alg) -- Step 2: Get the appropriate key based on kid local key = get_key_from_storage(kid) -- Your key lookup function -- Step 3: Verify with the correct key local verified_obj = jwt:verify_jwt_obj(key, jwt_obj) if verified_obj.verified then ngx.say("User: ", verified_obj.payload.sub) else ngx.status = ngx.HTTP_UNAUTHORIZED ngx.say("Verification failed: ", verified_obj.reason) end ``` -------------------------------- ### Loading and Verifying a JWT Object Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This Lua code provides methods to first load a JWT token into a JWT object and then verify it. `jwt:load_jwt` parses the token, and `jwt:verify_jwt_obj` performs the actual verification using a provided key and optional claim specifications. ```lua local jwt_obj = jwt:load_jwt(jwt_token) local verified = jwt:verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]]) ``` -------------------------------- ### Signing a JWT Token Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This Lua code demonstrates how to sign a JWT token using the `jwt:sign` method. It takes a secret key and a table containing the JWT header and payload as input, returning the signed JWT string. ```lua local jwt_token = jwt:sign( "lua-resty-jwt", { header={typ="JWT", alg="HS256"}, payload={foo="bar"} } ) ``` -------------------------------- ### JWT Signing API Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This section covers the API for signing JWTs. It allows you to create a JWT token from a Lua table, specifying the key and hashing algorithm. ```APIDOC ## POST /sign (Simulated) ### Description Signs a Lua table into a JWT token using a provided key and algorithm. ### Method POST (Simulated - this is a library function call) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **key** (string) - The secret key for signing. - **table_of_jwt** (table) - A Lua table containing 'header' and 'payload'. - **header** (table) - JWT header, must include 'typ' (e.g., 'JWT') and 'alg' (e.g., 'HS256', 'HS512', 'RS256'). - **payload** (table) - JWT payload containing claims. ### Request Example ```lua local jwt = require "resty.jwt" local jwt_token = jwt:sign( "your-secret-key", { header={typ="JWT", alg="HS256"}, payload={foo="bar", exp=1678886400} } ) ``` ### Response #### Success Response (200) - **jwt_token** (string) - The generated JWT string. #### Response Example ```json { "jwt_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJleHAiOjE2Nzg4ODY0MDB9.your_signature_here" } ``` ``` -------------------------------- ### Lua Require Statement Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Lua code to load the resty.jwt library after configuring the Lua package path in Nginx. ```lua local jwt = require "resty.jwt" ``` -------------------------------- ### Chaining Validators for Complex JWT Rules Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Illustrates how to chain multiple validators together to create sophisticated validation rules for JWT claims. This includes checking for claim existence, matching against multiple values, and defining custom validation logic. ```lua local jwt = require "resty.jwt" local validators = require "resty.jwt-validators" -- Chain validators for a single claim local strict_issuer = validators.chain( validators.required(), -- Must exist validators.equals_any_of({"issuer1", "issuer2"}) -- Must match ) -- Require at least one of multiple claims local require_auth_claim = validators.require_one_of({"nbf", "exp"}) -- Custom validator function local custom_role_validator = function(val, claim, jwt_json) if val == nil then return true end -- Optional check local allowed_roles = {admin = true, moderator = true, user = true} if not allowed_roles[val] then error("Invalid role: " .. tostring(val)) end return true end -- Combine all validations local claim_spec = { iss = strict_issuer, __jwt = require_auth_claim, -- Special: validates entire JWT object role = custom_role_validator, exp = validators.is_not_expired(), nbf = validators.opt_is_not_before() } local jwt_obj = jwt:verify("secret", jwt_token, claim_spec) ``` -------------------------------- ### Loading the lua-resty-jwt Library Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This code snippet shows how to load the lua-resty-jwt library within a Lua environment, typically used with ngx_lua. It requires setting the lua_package_path directive in Nginx configuration to point to the library's location. ```lua local jwt = require "resty.jwt" ``` -------------------------------- ### Whitelist Allowed Algorithms Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Restrict which signing algorithms are accepted to prevent algorithm confusion attacks. This is a security best practice when you know which algorithms your system uses. ```APIDOC ## Whitelist Allowed Algorithms ### Description Restrict which signing algorithms are accepted to prevent algorithm confusion attacks. This is a security best practice when you know which algorithms your system uses. ### Method `jwt:set_alg_whitelist()` `jwt:verify()` ### Endpoint N/A (Lua function calls) ### Parameters #### `jwt:set_alg_whitelist()` - **whitelist** (table) - A table where keys are algorithm names (e.g., "HS256", "RS256") and values are booleans (true to allow, false or absent to disallow). #### `jwt:verify()` - **key** (string) - The secret or public key for verification. - **jwt_token** (string) - The JWT token to verify. ### Request Example ```lua local jwt = require "resty.jwt" -- Allow only HS256 and HS512 algorithms jwt:set_alg_whitelist({ HS256 = true, HS512 = true }) -- Verification will fail if the token uses a non-whitelisted algorithm like RS256 local jwt_obj = jwt:verify("my-secret", jwt_token) ``` ### Response #### Success Response (Verified Token) - **verified** (boolean) - True if the token is valid and uses a whitelisted algorithm. - **payload** (table) - The decoded payload of the JWT. #### Error Response - **verified** (boolean) - False if verification fails or the algorithm is not whitelisted. - **reason** (string) - The reason for verification failure (e.g., "whitelist unsupported alg: RS256"). #### Response Example ```lua if not jwt_obj.verified then ngx.say("Rejected: ", jwt_obj.reason) end ``` ``` -------------------------------- ### Verifying a JWT Token Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This Lua code snippet illustrates how to verify a JWT token using the `jwt:verify` method. It takes a secret key and the JWT token string as input, returning a JWT object containing verification results. ```lua local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" .. ".eyJmb28iOiJiYXIifQ" .. ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY" local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token) ``` -------------------------------- ### Sample JWT Table Structure Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This snippet shows the typical structure of a JWT object as a Lua table, including header and payload sections. The header contains metadata like token type, algorithm, and encryption, while the payload holds the claims. ```lua { "header": {"typ": "JWE", "alg": "dir", "enc":"A128CBC-HS256"}, "payload": {"foo": "bar"} } ``` -------------------------------- ### JWT Verification API Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This section details the API for verifying JWTs. It checks the signature and optionally validates claims against the provided token and key. ```APIDOC ## GET /verify (Simulated) ### Description Verifies a JWT token against a key and optional claim specifications. Returns a table containing verification results. ### Method GET (Simulated - this is a library function call) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **key** (string | function) - The secret key (string) or a function to retrieve the key based on the 'kid' from the header. - **jwt_token** (string) - The JWT string to verify. - **claim_spec** (optional, multiple) - Additional claim specifications for validation (e.g., expiration, issuer). ### Request Example ```lua local jwt = require "resty.jwt" local jwt_obj = jwt:verify("your-secret-key", "your_jwt_token_here") -- Example with claim validation: local jwt_obj_validated = jwt:verify("your-secret-key", "your_jwt_token_here", {exp = true, iss = "your_issuer"}) ``` ### Response #### Success Response (200) - **jwt_obj** (table) - A table containing verification details: - **raw_header** (string) - The raw, base64-encoded header. - **raw_payload** (string) - The raw, base64-encoded payload. - **signature** (string) - The signature part of the JWT. - **header** (table) - The decoded JWT header. - **payload** (table) - The decoded JWT payload. - **verified** (boolean) - True if the signature is valid, false otherwise. - **valid** (boolean) - True if the token is considered valid (including claim checks), false otherwise. - **reason** (string) - If verification failed, provides the reason. #### Response Example ```json { "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", "raw_payload": "eyJmb28iOiJiYXIiLCJleHAiOjE2Nzg4ODY0MDB9", "signature": "your_signature_here", "header": {"typ": "JWT", "alg": "HS256"}, "payload": {"foo": "bar", "exp": 1678886400}, "verified": true, "valid": true, "reason": null } ``` ``` -------------------------------- ### Load and Verify JWT Object API Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Provides separate functions to load a JWT token into an object and then verify that object. This allows for more granular control. ```APIDOC ## Utility Functions for JWT Objects ### Description These functions allow you to first load a JWT token into a structured object and then verify that object. This is useful for inspecting the token before or during verification. ### Method N/A (Library functions) ### Endpoint N/A (Library functions) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **load_jwt(jwt_token)**: - **jwt_token** (string) - The JWT string to load. - **verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]])**: - **key** (string | function) - The secret key or a key retrieval function. - **jwt_obj** (table) - The JWT object returned by `load_jwt`. - **claim_spec** (optional, multiple) - Additional claim specifications for validation. ### Request Example ```lua local jwt = require "resty.jwt" local jwt_token = "your_jwt_token_here" local jwt_obj = jwt:load_jwt(jwt_token) if jwt_obj and jwt_obj.valid then local is_verified = jwt:verify_jwt_obj("your-secret-key", jwt_obj) if is_verified then ngx.say("JWT is valid and verified.") else ngx.say("JWT signature verification failed.") end else ngx.say("JWT is invalid or could not be loaded: " .. (jwt_obj.reason or "unknown")) end ``` ### Response #### Success Response (200) - **load_jwt**: Returns a `jwt_obj` table (see `verify` response example). - **verify_jwt_obj**: Returns a boolean (`true` if verified, `false` otherwise). #### Response Example ```json { "jwt_obj": { "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", "raw_payload": "eyJmb28iOiJiYXIifQ", "signature": "wrong-signature", "header": {"typ": "JWT", "alg": "HS256"}, "payload": {"foo": "bar"}, "verified": false, "valid": true, "reason": "signature mismatched: wrong-signature" } } ``` ``` -------------------------------- ### JWT Claim Validation with Lua-Resty-JWT-Validators Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Shows how to validate JWT claims such as expiration, issuer, and audience using the resty-jwt-validators library. It also demonstrates setting system leeway for clock skew tolerance and performing custom numeric validations. ```lua local jwt = require "resty.jwt" local validators = require "resty.jwt-validators" -- Configure system leeway for time-based validations (clock skew tolerance) validators.set_system_leeway(120) -- 120 seconds -- Define claim validators local claim_spec = { -- Issuer must be one of these values iss = validators.equals_any_of({"auth.myapp.com", "auth-backup.myapp.com"}), -- Subject must match a pattern sub = validators.matches("^user_[0-9]+$"), -- Token must not be expired (checks exp claim) exp = validators.is_not_expired(), -- Token must be valid (checks nbf claim) nbf = validators.opt_is_not_before(), -- opt_ = optional, won't fail if missing -- Custom audience check aud = validators.equals("my-api"), -- Numeric claim validation level = validators.greater_than_or_equal(5) } -- Verify with claim validation local jwt_obj = jwt:verify("my-secret", jwt_token, claim_spec) if jwt_obj.verified then ngx.say("Valid token for user: ", jwt_obj.payload.sub) else ngx.say("Validation failed: ", jwt_obj.reason) -- Example reasons: "'exp' claim expired at Thu, 14 Oct 2021 12:00:00 GMT" -- "'iss' claim is required" -- "Claim 'level' ('3') returned failure" end ``` -------------------------------- ### Importing JWT Validators Library Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Shows how to import the `resty.jwt-validators` library in Lua. This library provides a collection of pre-built validator functions to simplify common JWT claim validation tasks. ```lua local validators = require "resty.jwt-validators" ``` -------------------------------- ### Legacy Validation Options Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Use simplified validation options for common scenarios like token lifetime checks and issuer whitelisting. These options are automatically converted to the equivalent claim_spec validators. ```APIDOC ## Legacy Validation Options ### Description Use simplified validation options for common scenarios like token lifetime checks and issuer whitelisting. These options are automatically converted to the equivalent claim_spec validators. ### Method `jwt:verify()` ### Endpoint N/A (Lua function call) ### Parameters #### Request Body (Options Table) - **lifetime_grace_period** (number) - Optional - Allows a specified number of seconds of clock skew for token expiration. - **require_exp_claim** (boolean) - Optional - If true, the token must contain an `exp` claim. - **require_nbf_claim** (boolean) - Optional - If true, the token must contain an `nbf` claim. - **valid_issuers** (table) - Optional - A list of valid issuer identifiers. ### Request Example ```lua local jwt = require "resty.jwt" local jwt_obj = jwt:verify("my-secret", jwt_token, { lifetime_grace_period = 120, require_exp_claim = true, valid_issuers = {"auth.myapp.com", "backup-auth.myapp.com"} }) ``` ### Response #### Success Response (Verified Token) - **verified** (boolean) - True if the token is valid. - **payload** (table) - The decoded payload of the JWT. #### Error Response - **verified** (boolean) - False if the token is invalid. - **reason** (string) - The reason for verification failure. #### Response Example ```lua if jwt_obj.verified then ngx.say("Token valid until: ", os.date("%c", jwt_obj.payload.exp)) else ngx.say("Error: ", jwt_obj.reason) end ``` ### Equivalent Claim Spec ```lua local validators = require "resty.jwt-validators" validators.set_system_leeway(120) local equivalent_spec = { __jwt = validators.require_one_of({"nbf", "exp"}), iss = validators.equals_any_of({"auth.myapp.com", "backup-auth.myapp.com"}), exp = validators.is_not_expired(), nbf = validators.opt_is_not_before() } ``` ``` -------------------------------- ### Equivalent Claim Spec for Require EXP Claim Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Details the claim specification equivalent to setting `require_exp_claim` to true. This ensures the 'exp' claim is present and valid. ```lua { exp = validators.is_not_expired(), } ``` -------------------------------- ### Whitelist Allowed JWT Signing Algorithms Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Restrict which signing algorithms are accepted to prevent algorithm confusion attacks. This is a security best practice when you know which algorithms your system uses. Only whitelisted algorithms will be permitted during verification. ```lua local jwt = require "resty.jwt" -- Only allow specific algorithms (prevent "none" and algorithm switching attacks) jwt:set_alg_whitelist({ HS256 = true, HS512 = true -- RS256 explicitly NOT allowed }) -- Now verification will fail if token uses non-whitelisted algorithm local jwt_obj = jwt:verify("my-secret", jwt_token) if not jwt_obj.verified then -- If token was signed with RS256, reason will be: -- "whitelist unsupported alg: RS256" ngx.say("Rejected: ", jwt_obj.reason) end -- For RSA-only systems: jwt:set_alg_whitelist({ RS256 = true, RS512 = true }) ``` -------------------------------- ### Equivalent Claim Spec for Valid Issuers Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Illustrates the claim specification equivalent to using the `valid_issuers` validation option. It checks if the 'iss' claim matches any of the provided valid issuers. ```lua { iss = validators.equals_any_of(valid_issuers), } ``` -------------------------------- ### Equivalent Claim Spec for Require NBF Claim Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Presents the claim specification equivalent to setting `require_nbf_claim` to true. This ensures the 'nbf' claim is present and valid. ```lua { nbf = validators.is_not_before(), } ``` -------------------------------- ### Equivalent Claim Spec for Lifetime Grace Period Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Shows the equivalent claim specification for using the `lifetime_grace_period` validation option. It ensures the JWT has either an 'nbf' or 'exp' claim and validates them using appropriate validators. ```lua { __jwt = validators.require_one_of({ "nbf", "exp" }), nbf = validators.opt_is_not_before(), exp = validators.opt_is_not_expired() } ``` -------------------------------- ### Verify JWT Token with Signature and Claims Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Verifies and decodes a JWT token, checking signature validity and optionally validating claims. It returns a jwt_obj table indicating verification status, decoded header, payload, and any failure reasons. Dependencies include resty.jwt and cjson. ```lua local jwt = require "resty.jwt" local cjson = require "cjson" local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY" -- Basic verification with HMAC secret local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token) if jwt_obj.verified then ngx.say("Token is valid!") ngx.say("Payload: ", cjson.encode(jwt_obj.payload)) -- Output: {"foo":"bar"} else ngx.status = ngx.HTTP_UNAUTHORIZED ngx.say("Verification failed: ", jwt_obj.reason) -- Possible reasons: "signature mismatch", "invalid jwt string", etc. end -- Verification with RSA public key local rsa_public_key = [[ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2mKqH... -----END PUBLIC KEY----- ]] local jwt_obj_rsa = jwt:verify(rsa_public_key, jwt_token_rsa) -- jwt_obj structure on success: -- { -- "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", -- "raw_payload": "eyJmb28iOiJiYXIifQ", -- "header": {"typ": "JWT", "alg": "HS256"}, -- "payload": {"foo": "bar"}, -- "signature": "VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY", -- "verified": true, -- "valid": true, -- "reason": "everything is awesome~ :p" -- } ``` -------------------------------- ### Sign JWE (JSON Web Encryption) Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md This section describes the API for signing JSON Web Encrypted (JWE) tokens. It supports encryption algorithms for both the key and the payload. ```APIDOC ## POST /sign-jwe (Simulated) ### Description Signs a Lua table into a JWE token. This involves encrypting the content using specified algorithms for key management and payload encryption. ### Method POST (Simulated - this is a library function call) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **key** (string) - The secret key for encryption. - **table_of_jwt** (table) - A Lua table containing 'header' and 'payload'. - **header** (table) - JWE header, must include 'alg' (e.g., 'dir') for key encryption and 'enc' (e.g., 'A128CBC-HS256', 'A256CBC-HS512') for payload encryption. - **payload** (table) - The plaintext payload to be encrypted. ### Request Example ```lua local jwt = require "resty.jwt" local jwe_token = jwt:sign_jwe( "your-encryption-key", { header={alg="dir", enc="A128CBC-HS256"}, payload={sensitive_data="user_info"} } ) ``` ### Response #### Success Response (200) - **jwe_token** (string) - The generated JWE token string. #### Response Example ```json { "jwe_token": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..your_encrypted_key..your_encrypted_data..your_authentication_tag" } ``` ``` -------------------------------- ### Legacy JWT Validation Options Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Use simplified validation options for common scenarios like token lifetime checks and issuer whitelisting. These options are automatically converted to the equivalent claim_spec validators. Supports grace periods, expiration requirements, and issuer whitelisting. ```lua local jwt = require "resty.jwt" -- Legacy validation with grace period and issuer whitelist local jwt_obj = jwt:verify("my-secret", jwt_token, { -- Allow 120 seconds of clock skew lifetime_grace_period = 120, -- Require the exp claim (token must have expiration) require_exp_claim = true, -- Optionally require nbf claim require_nbf_claim = false, -- Whitelist of valid issuers valid_issuers = {"auth.myapp.com", "backup-auth.myapp.com"} }) if jwt_obj.verified then ngx.say("Token valid until: ", os.date("%c", jwt_obj.payload.exp)) else ngx.say("Error: ", jwt_obj.reason) end -- Equivalent claim_spec (what the legacy options convert to): local validators = require "resty.jwt-validators" validators.set_system_leeway(120) local equivalent_spec = { __jwt = validators.require_one_of({"nbf", "exp"}), iss = validators.equals_any_of({"auth.myapp.com", "backup-auth.myapp.com"}), exp = validators.is_not_expired(), nbf = validators.opt_is_not_before() } ``` -------------------------------- ### Sign JWT Token with HMAC or RSA Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Creates and signs a JWT token using specified algorithms (HS256, HS512, RS256) with a secret or private key. The output is a base64-encoded JWT string comprising header, payload, and signature. Dependencies include resty.jwt. ```lua local jwt = require "resty.jwt" -- Sign with HMAC-SHA256 (symmetric key) local jwt_token = jwt:sign( "my-secret-key", { header = {typ = "JWT", alg = "HS256"}, payload = { sub = "user123", name = "John Doe", iat = ngx.time(), exp = ngx.time() + 3600, -- expires in 1 hour iss = "my-app" } } ) -- Result: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjM0NTY3ODkwLCJleHAiOjE2MzQ1NzE0OTAsImlzcyI6Im15LWFwcCJ9.signature" -- Sign with HMAC-SHA512 for stronger security local jwt_token_512 = jwt:sign( "my-secret-key", { header = {typ = "JWT", alg = "HS512"}, payload = {user_id = 456, role = "admin"} } ) -- Sign with RSA-SHA256 (asymmetric key) local rsa_private_key = [[ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA2mKqH... -----END RSA PRIVATE KEY----- ]] local jwt_token_rsa = jwt:sign( rsa_private_key, { header = {typ = "JWT", alg = "RS256"}, payload = {sub = "user789", permissions = {"read", "write"}} } ) ``` -------------------------------- ### Set Trusted Certificate Authority Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Configure trusted CA certificates for verifying RS256/RS512 tokens that include X.509 certificates (x5c) or certificate URLs (x5u) in their headers. ```APIDOC ## Set Trusted Certificate Authority ### Description Configure trusted CA certificates for verifying RS256/RS512 tokens that include X.509 certificates (x5c) or certificate URLs (x5u) in their headers. ### Method `jwt:set_trusted_certs_file()` `jwt:set_x5u_content_retriever()` `jwt:verify()` ### Endpoint N/A (Lua function calls) ### Parameters #### `jwt:set_trusted_certs_file()` - **cert_file_path** (string) - Path to the file containing trusted CA certificates in PEM format. #### `jwt:set_x5u_content_retriever()` - **retriever_function** (function) - A function that takes `x5u_url`, `issuer`, and `kid` as arguments and returns the certificate content (PEM format) or throws an error. #### `jwt:verify()` - **key** (string|nil) - The public key or nil if the key is expected in the token's `x5c` or `x5u` header. - **jwt_token** (string) - The JWT token to verify. ### Request Example ```lua local jwt = require "resty.jwt" -- Set trusted CA certificates jwt:set_trusted_certs_file("/etc/nginx/certs/trusted-cas.pem") -- Set a custom retriever for x5u jwt:set_x5u_content_retriever(function(x5u_url, issuer, kid) local http = require "resty.http" local httpc = http.new() local res, err = httpc:request_uri(x5u_url, {ssl_verify = true}) if not res then error("Failed to fetch certificate: " .. err) end return res.body end) -- Verify a token with a certificate in its header (e.g., x5c) local jwt_obj = jwt:verify(nil, jwt_token) -- Key extracted from x5c ``` ### Response #### Success Response (Verified Token) - **verified** (boolean) - True if the token is valid and the certificate is trusted. - **payload** (table) - The decoded payload of the JWT. #### Error Response - **verified** (boolean) - False if verification fails. - **reason** (string) - The reason for verification failure (e.g., certificate validation error, untrusted CA). #### Response Example ```lua if jwt_obj.verified then ngx.say("Certificate-verified token for: ", jwt_obj.payload.sub) else ngx.say("Certificate verification failed: ", jwt_obj.reason) end ``` ``` -------------------------------- ### Sign and Verify JWE (Encrypted JWT) Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Create and verify encrypted JWT tokens using JWE (JSON Web Encryption) for payload confidentiality. Supports AES-CBC encryption with HMAC authentication. Requires a secret key of specific byte lengths for different encryption algorithms. ```lua local jwt = require "resty.jwt" local cjson = require "cjson" -- Secret key must be exactly 32 bytes for A128CBC-HS256 or 64 bytes for A256CBC-HS512 local encryption_key = "12345678901234567890123456789012" -- 32 bytes -- Sign a JWE token local jwe_token = jwt:sign( encryption_key, { header = { typ = "JWE", alg = "dir", -- Direct encryption enc = "A128CBC-HS256" -- AES-128-CBC with HMAC-SHA256 }, payload = { sub = "user123", secret_data = "sensitive information", credit_card = "4111-1111-1111-1111" -- Data that needs encryption } } ) -- JWE token has 5 parts: header.encrypted_key.iv.ciphertext.auth_tag -- Verify and decrypt JWE local jwt_obj = jwt:verify(encryption_key, jwe_token) if jwt_obj.verified then ngx.say("Decrypted payload: ", cjson.encode(jwt_obj.payload)) ngx.say("Secret data: ", jwt_obj.payload.secret_data) else ngx.say("Decryption failed: ", jwt_obj.reason) end -- Using stronger encryption (A256CBC-HS512) local strong_key = string.rep("x", 64) -- 64-byte key for A256CBC-HS512 local jwe_token_strong = jwt:sign( strong_key, { header = {alg = "dir", enc = "A256CBC-HS512"}, payload = {top_secret = "classified"} } ) ``` -------------------------------- ### JWT Validators: chain Function Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Demonstrates the usage of `validators.chain`. This function takes multiple validator functions as arguments and returns a single validator that executes them sequentially. If any validator in the chain fails, the chain stops. ```lua -- Example usage: -- local chained_validator = validators.chain(validators.required(), validators.equals("expected_value")) ``` -------------------------------- ### Sign and Verify JWE (Encrypted JWT) Source: https://context7.com/skylothar/lua-resty-jwt/llms.txt Create encrypted JWT tokens using JWE (JSON Web Encryption) for payload confidentiality. Supports AES-CBC encryption with HMAC authentication (A128CBC-HS256, A256CBC-HS512). ```APIDOC ## Sign and Verify JWE (Encrypted JWT) ### Description Create encrypted JWT tokens using JWE (JSON Web Encryption) for payload confidentiality. Supports AES-CBC encryption with HMAC authentication (A128CBC-HS256, A256CBC-HS512). ### Method `jwt:sign()` (for signing), `jwt:verify()` (for verification) ### Endpoint N/A (Lua function calls) ### Parameters #### `jwt:sign()` - **key** (string) - The encryption key. Must be 32 bytes for A128CBC-HS256 or 64 bytes for A256CBC-HS512. - **data** (table) - The payload and header information for the JWE. - **header** (table) - JWE header parameters. - **typ** (string) - Must be "JWE". - **alg** (string) - Encryption algorithm (e.g., "dir" for direct encryption). - **enc** (string) - Content encryption algorithm (e.g., "A128CBC-HS256", "A256CBC-HS512"). - **payload** (table) - The data to be encrypted. #### `jwt:verify()` - **key** (string) - The decryption key (same as the encryption key). - **jwe_token** (string) - The JWE token to verify and decrypt. ### Request Example (Signing) ```lua local jwt = require "resty.jwt" local encryption_key = "12345678901234567890123456789012" -- 32 bytes local jwe_token = jwt:sign( encryption_key, { header = { typ = "JWE", alg = "dir", enc = "A128CBC-HS256" }, payload = { sub = "user123", secret_data = "sensitive information" } } ) ``` ### Response #### `jwt:sign()` - **jwe_token** (string) - The generated JWE token. #### `jwt:verify()` (Success Response) - **verified** (boolean) - True if the JWE is valid and decrypted. - **payload** (table) - The decrypted payload. #### `jwt:verify()` (Error Response) - **verified** (boolean) - False if verification or decryption fails. - **reason** (string) - The reason for failure. #### Response Example (Verification) ```lua local jwt_obj = jwt:verify(encryption_key, jwe_token) if jwt_obj.verified then ngx.say("Decrypted payload: ", cjson.encode(jwt_obj.payload)) else ngx.say("Decryption failed: ", jwt_obj.reason) end ``` ``` -------------------------------- ### JWT Validators: equals Function Source: https://github.com/skylothar/lua-resty-jwt/blob/master/README.md Explains the `validators.equals` function. This is a simple validator that checks if the claim's value is strictly equal (`==`) to the provided `check_val`. It's useful for verifying exact matches of claim values. ```lua -- Example usage: -- local must_be_admin = validators.equals("admin") ```