-
Notifications
You must be signed in to change notification settings - Fork 225
/
token_validation.py
67 lines (54 loc) · 1.94 KB
/
token_validation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import jwt
from parse import parse
from datetime import datetime, timedelta
from flask import current_app as app
def encode_token(payload, private_key):
return jwt.encode(payload, private_key, algorithm='RS256')
def decode_token(token, public_key):
return jwt.decode(token, public_key, algoritms='RS256')
def generate_token_header(username, private_key):
'''
Generate a token header base on the username. Sign using the private key.
'''
payload = {
'username': username,
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(days=2),
}
token = encode_token(payload, private_key)
token = token.decode('utf8')
return f'Bearer {token}'
def validate_token_header(header, public_key):
'''
Validate that a token header is correct
If correct, it return the username, if not, it
returns None
'''
if not header:
app.logger.info('No header')
return None
# Retrieve the Bearer token
parse_result = parse('Bearer {}', header)
if not parse_result:
app.logger.info(f'Wrong format for header "{header}"')
return None
token = parse_result[0]
try:
decoded_token = decode_token(token.encode('utf8'), public_key)
except jwt.exceptions.DecodeError:
app.logger.warning(f'Error decoding header "{header}". '
'This may be key missmatch or wrong key')
return None
except jwt.exceptions.ExpiredSignatureError:
app.logger.error(f'Authentication header has expired')
return None
# Check expiry is in the token
if 'exp' not in decoded_token:
app.logger.warning('Token does not have expiry (exp)')
return None
# Check username is in the token
if 'username' not in decoded_token:
app.logger.warning('Token does not have username')
return None
app.logger.info('Header successfully validated')
return decoded_token['username']