I am writing web endpoints that take a JSON Web Token (JWT) and have to check the signature on the token. Since I am going to check the signature every time it makes the most sense to me that I should break this step out into a function because DRY.
However, the only way to check whether a JWT is signed correctly is to decode it with its secret key and catch an error. This leads me to the following function:
def is_valid_token(token_string, secret_key):
try:
jwt.decode(token_string, secret_key)
return True
except jwt.DecodeError:
return False
This works fine in terms of validating the tokens, however it seems really wasteful that I have this function that will check if the token is valid by decoding and then immediately after this function I am going to have to decode again. That is to say I would do:
if not is_valid_token(token_string, secret_key):
# Respond with an error to the client
else:
token_data = jwt.decode(token_string, secret_key)
In this case I am decoding to check if it's valid and then if it is I'm decoding again. In C/C++ I would pass a variable by reference to capture the decoded data and then return true or false. Is there any way to do such a thing in Python?
It occurred to me that I might be able to get away with this by passing in an empty list to capture the decoded data but that seems really inelegant. Is there a Pythonic way to do this?
After discussing with Nullman we've come to the following solution
def is_valid_token(jwt_string, secret_key, reference_list):
try:
data = jwt.decode(jwt_string, secret_key)
reference_list.append(data)
return True
except:
return False
reference_var = []
if not is_valid_token(jwt_string, secret_key, reference_var):
# Respond with an error to the client
else:
data = reference_var[0]