Skip to content

Instantly share code, notes, and snippets.

@oshinko
Last active January 30, 2018 02:43
Show Gist options
  • Save oshinko/1a2a1b2cd961cb190552efea208219ea to your computer and use it in GitHub Desktop.
Save oshinko/1a2a1b2cd961cb190552efea208219ea to your computer and use it in GitHub Desktop.
HMAC Web Token Example
import hmac
from datetime import datetime, timedelta
from hashlib import sha256
class Session:
secret = b'Please enter your desired passphrase'
def __init__(self, *, user=None, token=None):
if user:
self.user = user
elif token:
self.token = token
else:
self.expires = datetime.fromtimestamp(0)
self.valid = False
@property
def user(self):
return self._user
@user.setter
def user(self, value):
self._user = value
self.expires = datetime.now() + timedelta(days=3)
ubin = self.user.encode()
ulen = len(ubin).to_bytes(1, 'big')
ebin = int(self.expires.timestamp()).to_bytes(8, 'big').lstrip(b'\0')
elen = len(ebin).to_bytes(1, 'big')
cls = self.__class__
self.sign = hmac.new(cls.secret, ubin + ebin, sha256).digest()
self.valid = True
self._token = (ulen + elen + ubin + ebin + self.sign).hex()
@property
def token(self):
return self._token
@token.setter
def token(self, value):
try:
b = bytes.fromhex(value)
ulen, elen = b[:2]
uend = 2 + ulen
eend = uend + elen
ubin = b[2:uend]
ebin = b[uend:eend]
sign = hmac.new(self.__class__.secret, ubin + ebin, sha256)
self._token = value
self._user = ubin.decode()
self.expires = datetime.fromtimestamp(int.from_bytes(ebin, 'big'))
self.sign = b[eend:]
self.valid = self.sign == sign.digest()
except Exception:
pass
if __name__ == '__main__':
u = 'Satoshi'
s = Session(user=u)
s = Session(token=s.token)
assert s.user == u
print('OK')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment