4
4
5
5
from . import oauth2
6
6
7
+ def decode_part (raw , encoding = "utf-8" ):
8
+ """Decode a part of the JWT.
7
9
8
- def base64decode (raw ):
9
- """A helper can handle a padding-less raw input"""
10
+ JWT is encoded by padding-less base64url,
11
+ based on `JWS specs <https://tools.ietf.org/html/rfc7515#appendix-C>`_.
12
+
13
+ :param encoding:
14
+ If you are going to decode the first 2 parts of a JWT, i.e. the header
15
+ or the payload, the default value "utf-8" would work fine.
16
+ If you are going to decode the last part i.e. the signature part,
17
+ it is a binary string so you should use `None` as encoding here.
18
+ """
10
19
raw += '=' * (- len (raw ) % 4 ) # https://stackoverflow.com/a/32517907/728675
11
- return base64 .b64decode (raw ).decode ("utf-8" )
20
+ raw = str (
21
+ # On Python 2.7, argument of urlsafe_b64decode must be str, not unicode.
22
+ # This is not required on Python 3.
23
+ raw )
24
+ output = base64 .urlsafe_b64decode (raw )
25
+ if encoding :
26
+ output = output .decode (encoding )
27
+ return output
12
28
29
+ base64decode = decode_part # Obsolete. For backward compatibility only.
13
30
14
31
def decode_id_token (id_token , client_id = None , issuer = None , nonce = None , now = None ):
15
32
"""Decodes and validates an id_token and returns its claims as a dictionary.
@@ -19,7 +36,7 @@ def decode_id_token(id_token, client_id=None, issuer=None, nonce=None, now=None)
19
36
and it may contain other optional content such as "preferred_username",
20
37
`maybe more <https://openid.net/specs/openid-connect-core-1_0.html#Claims>`_
21
38
"""
22
- decoded = json .loads (base64decode (id_token .split ('.' )[1 ]))
39
+ decoded = json .loads (decode_part (id_token .split ('.' )[1 ]))
23
40
err = None # https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
24
41
if issuer and issuer != decoded ["iss" ]:
25
42
# https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse
0 commit comments