def _unpack_token_json(token):
    """
    Unpack a JSON-serialized JWT
    Returns (headers, payload, signatures) on success
    Raises DecodeError on bad input
    """
    if not isinstance(token, dict):
        raise DecodeError("Not a dict")

    if not token.has_key('payload'):
        raise DecodeError("Missing 'payload' field")

    for k in ['header', 'signature']:
        if not token.has_key(k):
            raise DecodeError("Missing '{}' field".format(k))

        if not isinstance(token[k], list):
            raise DecodeError("Field '{}' is not a string".format(k))

    headers = []
    signatures = []
    signing_inputs = []
    payload = None

    try:
        headers = [base64url_decode(str(h)) for h in token['header']]
    except (TypeError, binascii.Error):
        raise DecodeError("Invalid header padding")

    try:
        payload_data = base64url_decode(str(token['payload']))
    except (TypeError, binascii.Error):
        raise DecodeError("Invalid payload padding")

    try:
        payload = json.loads(payload_data.decode('utf-8'))
    except ValueError as e:
        raise DecodeError('Invalid payload string: {}'.format(e))

    try:
        signatures = [base64url_decode(str(s)) for s in token['signature']]
    except (TypeError, binascii.Error):
        raise DecodeError("Invalid crypto padding")

    for header_b64 in token['header']:
        signing_inputs.append( b'{}.{}'.format(header_b64, token['payload']) )

    return (headers, payload, signatures, signing_inputs)