I'm trying to create a expire token generator. However when i for instance use generate_token
and then use the token in get_token_value
i keep getting cryptography.fernet.InvalidToken
i guess this is a issue with the encoding in the two functions, but i'm not quite sure what im missing?
generator
from datetime import datetime, timedelta
import cryptography
from cryptography.fernet import Fernet
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_text
class ExpiringTokenGenerator(object):
FERNET_KEY = Fernet.generate_key()
fernet = Fernet(FERNET_KEY)
DATE_FORMAT = '%Y-%m-%d %H-%M-%S'
EXPIRATION_DAYS = 1
def _get_time(self):
"""Returns a string with the current UTC time"""
return datetime.utcnow().strftime(self.DATE_FORMAT)
def _parse_time(self, d):
"""Parses a string produced by _get_time and returns a datetime object"""
return datetime.strptime(d, self.DATE_FORMAT)
def generate_token(self, text):
"""Generates an encrypted token"""
full_text = str(text) + '|' + self._get_time()
token = self.fernet.encrypt(bytes(full_text, 'utf-8'))
return token
def get_token_value(self, token):
"""Gets a value from an encrypted token.
Returns None if the token is invalid or has expired.
"""
try:
value = self.fernet.decrypt(bytes(token, 'utf-8'))
separator_pos = value.rfind('|')
text = value[: separator_pos]
token_time = self._parse_time(value[separator_pos + 1: ])
print(token_time)
if token_time + timedelta(self.EXPIRATION_DAYS) < datetime.utcnow():
return None
except cryptography.fernet.InvalidToken:
return None
return text
def is_valid_token(self, token):
return self.get_token_value(token) != None
invoice_activation_token = ExpiringTokenGenerator()
What if you casted full_text
as bytes first? Would that work?
from datetime import datetime
from cryptography.fernet import Fernet
FERNET_KEY = Fernet.generate_key()
fernet = Fernet(FERNET_KEY)
get_time = datetime.utcnow().strftime('%Y-%m-%d %H-%M-%S')
text = 'abc'
full_text = bytes(str(text) + '|' + get_time, encoding='utf-8')
token = fernet.encrypt(full_text)
value = fernet.decrypt(token)
print('Token:', token)
print('Value:', value)
Returns:
Token: b'gAAAAABaIIPXtLrJ6YoJWUq9o9i5Q-1dCJ9Iae4mczFhHmW-UUQUKkgsPcm0MxzIJbBbIeziY3W-b2joT37kG-RxueEhwlx-x8n4B224thTWuebY1FfYXjI='
Value: b'abc|2017-11-30 22-19-03'