aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2022-07-11 13:28:29 +0100
committerMatthew Wild <mwild1@gmail.com>2022-07-11 13:28:29 +0100
commit23458111dcf59d6c64e77f3286dbaa752539b77a (patch)
tree46783940a629f9ad93a3b6bb7702d19b0b5003ba
parentfad58c5ab2fa449aea07eca2a99a1b5e30a22711 (diff)
downloadprosody-23458111dcf59d6c64e77f3286dbaa752539b77a.tar.gz
prosody-23458111dcf59d6c64e77f3286dbaa752539b77a.zip
util.jwt: Provide built-in token expiry support (defaults to 3600s lifetime)
To avoid every user of the library needing to add and verify expiry info, this is now handled by util.jwt itself (if not overridden or disabled). Issuing tokens that are valid forever is bad practice and rarely desired, and the default token lifetime is now 3600s (1 hour).
-rw-r--r--util/jwt.lua31
1 files changed, 28 insertions, 3 deletions
diff --git a/util/jwt.lua b/util/jwt.lua
index 7bd98eb1..3501d9f2 100644
--- a/util/jwt.lua
+++ b/util/jwt.lua
@@ -152,21 +152,46 @@ local algorithms = {
PS256 = new_rsa_algorithm("PS256"), PS384 = new_rsa_algorithm("PS384"), PS512 = new_rsa_algorithm("PS512");
};
-local function new_signer(algorithm, key_input)
+local function new_signer(algorithm, key_input, options)
local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm);
local key = (impl.load_private_key or impl.load_key)(key_input);
local sign = impl.sign;
+ local default_ttl = (options and options.default_ttl) or 3600;
return function (payload)
+ local issued_at;
+ if not payload.iat then
+ issued_at = os.time();
+ payload.iat = issued_at;
+ end
+ if not payload.exp then
+ payload.exp = (issued_at or os.time()) + default_ttl;
+ end
return sign(key, payload);
end
end
-local function new_verifier(algorithm, key_input)
+local function new_verifier(algorithm, key_input, options)
local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm);
local key = (impl.load_public_key or impl.load_key)(key_input);
local verify = impl.verify;
+ local check_expiry = not (options and options.accept_expired);
+ local claim_verifier = options and options.claim_verifier;
return function (token)
- return verify(key, token);
+ local ok, payload = verify(key, token);
+ if ok then
+ local expires_at = check_expiry and payload.exp;
+ if expires_at then
+ if type(expires_at) ~= "number" then
+ return nil, "invalid-expiry";
+ elseif expires_at < os.time() then
+ return nil, "token-expired";
+ end
+ end
+ if claim_verifier and not claim_verifier(payload) then
+ return nil, "incorrect-claims";
+ end
+ end
+ return ok, payload;
end
end