Comparison

util/jwt.lua @ 12705:008a7097fdc5

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).
author Matthew Wild <mwild1@gmail.com>
date Mon, 11 Jul 2022 13:28:29 +0100 (2022-07-11)
parent 12704:31a2bd84191d
child 12706:108b1758bd8d
comparison
equal deleted inserted replaced
12704:31a2bd84191d 12705:008a7097fdc5
150 ES256 = new_ecdsa_algorithm("ES256", crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify); 150 ES256 = new_ecdsa_algorithm("ES256", crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify);
151 RS256 = new_rsa_algorithm("RS256"), RS384 = new_rsa_algorithm("RS384"), RS512 = new_rsa_algorithm("RS512"); 151 RS256 = new_rsa_algorithm("RS256"), RS384 = new_rsa_algorithm("RS384"), RS512 = new_rsa_algorithm("RS512");
152 PS256 = new_rsa_algorithm("PS256"), PS384 = new_rsa_algorithm("PS384"), PS512 = new_rsa_algorithm("PS512"); 152 PS256 = new_rsa_algorithm("PS256"), PS384 = new_rsa_algorithm("PS384"), PS512 = new_rsa_algorithm("PS512");
153 }; 153 };
154 154
155 local function new_signer(algorithm, key_input) 155 local function new_signer(algorithm, key_input, options)
156 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm); 156 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm);
157 local key = (impl.load_private_key or impl.load_key)(key_input); 157 local key = (impl.load_private_key or impl.load_key)(key_input);
158 local sign = impl.sign; 158 local sign = impl.sign;
159 local default_ttl = (options and options.default_ttl) or 3600;
159 return function (payload) 160 return function (payload)
161 local issued_at;
162 if not payload.iat then
163 issued_at = os.time();
164 payload.iat = issued_at;
165 end
166 if not payload.exp then
167 payload.exp = (issued_at or os.time()) + default_ttl;
168 end
160 return sign(key, payload); 169 return sign(key, payload);
161 end 170 end
162 end 171 end
163 172
164 local function new_verifier(algorithm, key_input) 173 local function new_verifier(algorithm, key_input, options)
165 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm); 174 local impl = assert(algorithms[algorithm], "Unknown JWT algorithm: "..algorithm);
166 local key = (impl.load_public_key or impl.load_key)(key_input); 175 local key = (impl.load_public_key or impl.load_key)(key_input);
167 local verify = impl.verify; 176 local verify = impl.verify;
177 local check_expiry = not (options and options.accept_expired);
178 local claim_verifier = options and options.claim_verifier;
168 return function (token) 179 return function (token)
169 return verify(key, token); 180 local ok, payload = verify(key, token);
181 if ok then
182 local expires_at = check_expiry and payload.exp;
183 if expires_at then
184 if type(expires_at) ~= "number" then
185 return nil, "invalid-expiry";
186 elseif expires_at < os.time() then
187 return nil, "token-expired";
188 end
189 end
190 if claim_verifier and not claim_verifier(payload) then
191 return nil, "incorrect-claims";
192 end
193 end
194 return ok, payload;
170 end 195 end
171 end 196 end
172 197
173 return { 198 return {
174 new_signer = new_signer; 199 new_signer = new_signer;