def decode_token(encoded_token, csrf_value=None): """ Returns the decoded token (python dict) from an encoded JWT. This does all the checks to insure that the decoded token is valid before returning it. :param encoded_token: The encoded JWT to decode into a python dict. :param csrf_value: Expected CSRF double submit value (optional) """ return decode_jwt(encoded_token=encoded_token, secret=config.decode_key, algorithm=config.algorithm, identity_claim_key=config.identity_claim_key, user_claims_key=config.user_claims_key, csrf_value=csrf_value)
def _decode_jwt_from_query_string(param_name): # Verify we have the query string token = request.args.get(param_name, None) if not token: raise NoAuthorizationError("Missing {} query param".format(param_name)) return decode_jwt( encoded_token=token, secret=config.decode_key, algorithm=config.algorithm, csrf_value=None, user_claims_key=config.user_claims_key, identity_claim_key=config.identity_claim_key )
def decode_token(encoded_token, csrf_value=None, allow_expired=False): """ Returns the decoded token (python dict) from an encoded JWT. This does all the checks to insure that the decoded token is valid before returning it. :param encoded_token: The encoded JWT to decode into a python dict. :param csrf_value: Expected CSRF double submit value (optional) :param allow_expired: Options to ignore exp claim validation in token :return: Dictionary containing contents of the JWT """ jwt_manager = _get_jwt_manager() unverified_claims = jwt.decode(encoded_token, verify=False, algorithms=config.algorithm) unverified_headers = jwt.get_unverified_header(encoded_token) # Attempt to call callback with both claims and headers, but fallback to just claims # for backwards compatibility # Added possibility to disable audience check verify_audience = True if config.audience is None: verify_audience = False try: secret = jwt_manager._decode_key_callback(unverified_claims, unverified_headers) except TypeError: msg = ( "The single-argument (unverified_claims) form of decode_key_callback ", "is deprecated. Update your code to use the two-argument form ", "(unverified_claims, unverified_headers).") warn(msg, DeprecationWarning) secret = jwt_manager._decode_key_callback(unverified_claims) return decode_jwt(encoded_token=encoded_token, secret=secret, algorithm=config.algorithm, identity_claim_key=config.identity_claim_key, user_claims_key=config.user_claims_key, csrf_value=csrf_value, audience=config.audience, leeway=config.leeway, allow_expired=allow_expired, verify_audience=verify_audience)
def decode_token(encoded_token, csrf_value=None): """ Returns the decoded token (python dict) from an encoded JWT. This does all the checks to insure that the decoded token is valid before returning it. :param encoded_token: The encoded JWT to decode into a python dict. :param csrf_value: Expected CSRF double submit value (optional) """ jwt_manager = _get_jwt_manager() unverified_claims = jwt.decode(encoded_token, verify=False, algorithms=config.algorithm) secret = jwt_manager._decode_key_callback(unverified_claims) return decode_jwt(encoded_token=encoded_token, secret=secret, algorithm=config.algorithm, identity_claim_key=config.identity_claim_key, user_claims_key=config.user_claims_key, csrf_value=csrf_value)
def wrapper(*args, **kwargs): jwt_token = request.json.get('refresh_token', None) if not jwt_token: raise NoAuthorizationError("Missing refresh token") decoded_token = decode_jwt( jwt_token, config.decode_key, config.algorithm, csrf=False) # Make sure the type of token we received matches the request type we expect if decoded_token['type'] != 'refresh': raise WrongTokenError('Only refresh tokens can access this endpoint') # If blacklisting is enabled, see if this token has been revoked #if config.blacklist_enabled: #check_if_token_revoked(decoded_token) ctx_stack.top.jwt = decoded_token _load_user(decoded_token['identity']) return fn(*args, **kwargs)
def create_access_token(self, identity, fresh=False, expires_delta=None): """ Creates a new access token :param identity: The identity of this token. This can be any data that is json serializable. It can also be an object, in which case you can use the user_identity_loader to define a function that will be called to pull a json serializable identity out of this object. This is useful so you don't need to query disk twice, once for initially finding the identity in your login endpoint, and once for setting addition data in the JWT via the user_claims_loader :param fresh: If this token should be marked as fresh, and can thus access fresh_jwt_required protected endpoints. Defaults to False :param expires_delta: A datetime.timedelta for how long this token should last before it expires. If this is None, it will use the 'JWT_ACCESS_TOKEN_EXPIRES` config value :return: A new access token """ if expires_delta is None: expires_delta = config.access_expires access_token = encode_access_token( identity=self._user_identity_callback(identity), secret=config.encode_key, algorithm=config.algorithm, expires_delta=expires_delta, fresh=fresh, user_claims=self._user_claims_callback(identity), csrf=config.csrf_protect) if config.blacklist_enabled and config.blacklist_access_tokens: decoded_token = decode_jwt(access_token, config.decode_key, config.algorithm, csrf=config.csrf_protect) store_token(decoded_token, revoked=False) return access_token
def test_decode_invalid_jwt(self): with self.app.test_request_context(): # Verify underlying pyjwt expires verification works with self.assertRaises(jwt.ExpiredSignatureError): token_data = { 'exp': datetime.utcnow() - timedelta(minutes=5), } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Missing jti with self.assertRaises(JWTDecodeError): token_data = { 'exp': datetime.utcnow() + timedelta(minutes=5), 'identity': 'banana', 'type': 'refresh' } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Missing identity with self.assertRaises(JWTDecodeError): token_data = { 'jti': 'banana', 'exp': datetime.utcnow() + timedelta(minutes=5), 'type': 'refresh' } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Missing type with self.assertRaises(JWTDecodeError): token_data = { 'jti': 'banana', 'identity': 'banana', 'exp': datetime.utcnow() + timedelta(minutes=5), } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Missing fresh in access token with self.assertRaises(JWTDecodeError): token_data = { 'jti': 'banana', 'identity': 'banana', 'exp': datetime.utcnow() + timedelta(minutes=5), 'type': 'access', 'user_claims': {} } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Missing user claims in access token with self.assertRaises(JWTDecodeError): token_data = { 'jti': 'banana', 'identity': 'banana', 'exp': datetime.utcnow() + timedelta(minutes=5), 'type': 'access', 'fresh': True } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Bad token type with self.assertRaises(JWTDecodeError): token_data = { 'jti': 'banana', 'identity': 'banana', 'exp': datetime.utcnow() + timedelta(minutes=5), 'type': 'banana', 'fresh': True, 'user_claims': 'banana' } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) # Missing csrf in csrf enabled token with self.assertRaises(JWTDecodeError): token_data = { 'jti': 'banana', 'identity': 'banana', 'exp': datetime.utcnow() + timedelta(minutes=5), 'type': 'access', 'fresh': True, 'user_claims': 'banana' } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') decode_jwt(encoded_token, 'secret', 'HS256', csrf=True)
def test_decode_jwt(self): # Test decoding a valid access token with self.app.test_request_context(): now = datetime.utcnow() now_ts = calendar.timegm(now.utctimetuple()) token_data = { 'exp': now + timedelta(minutes=5), 'iat': now, 'nbf': now, 'jti': 'banana', 'identity': 'banana', 'fresh': True, 'type': 'access', 'user_claims': { 'foo': 'bar' }, } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') data = decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) self.assertIn('exp', data) self.assertIn('iat', data) self.assertIn('nbf', data) self.assertIn('jti', data) self.assertIn('identity', data) self.assertIn('fresh', data) self.assertIn('type', data) self.assertIn('user_claims', data) self.assertEqual(data['exp'], now_ts + (5 * 60)) self.assertEqual(data['iat'], now_ts) self.assertEqual(data['nbf'], now_ts) self.assertEqual(data['jti'], 'banana') self.assertEqual(data['identity'], 'banana') self.assertEqual(data['fresh'], True) self.assertEqual(data['type'], 'access') self.assertEqual(data['user_claims'], {'foo': 'bar'}) # Test decoding a valid refresh token with self.app.test_request_context(): now = datetime.utcnow() now_ts = calendar.timegm(now.utctimetuple()) token_data = { 'exp': now + timedelta(minutes=5), 'iat': now, 'nbf': now, 'jti': 'banana', 'identity': 'banana', 'type': 'refresh', } encoded_token = jwt.encode(token_data, 'secret', 'HS256').decode('utf-8') data = decode_jwt(encoded_token, 'secret', 'HS256', csrf=False) self.assertIn('exp', data) self.assertIn('iat', data) self.assertIn('nbf', data) self.assertIn('jti', data) self.assertIn('identity', data) self.assertIn('type', data) self.assertEqual(data['exp'], now_ts + (5 * 60)) self.assertEqual(data['iat'], now_ts) self.assertEqual(data['nbf'], now_ts) self.assertEqual(data['jti'], 'banana') self.assertEqual(data['identity'], 'banana') self.assertEqual(data['type'], 'refresh')
def get_csrf_token(encoded_token): token = decode_jwt(encoded_token, config.decode_key, config.algorithm, csrf=True) return token['csrf']
def decode_token(token): return decode_jwt(encoded_token=token, secret=config.decode_key, algorithm=config.algorithm, csrf_value=None, user_claims_key=config.user_claims_key, identity_claim_key=config.identity_claim_key)
def get_username_from_token(token): try: username = tokens.decode_jwt(token, config.decode_key, config.algorithm, csrf=False)["identity"] except (DecodeError, ExpiredSignatureError): username = None return username
def decode_token(token): return decode_jwt(encoded_token=token, secret=config.decode_key, algorithm=config.algorithm, csrf_value=None, user_claims_key=config.user_claims_key, identity_claim_key=config.identity_claim_key)