diff --git a/jose/jws.py b/jose/jws.py
index 293b32a..8d7bce6 100644
--- a/jose/jws.py
+++ b/jose/jws.py
@@ -225,28 +225,27 @@ def _sig_matches_keys(keys, signing_input, signature, alg):
 def _get_keys(key):
 
     try:
-        key = json.loads(key)
+        key = json.loads(key, parse_int=str, parse_float=str)
     except Exception:
         pass
 
-    # JWK Set per RFC 7517
-    if 'keys' in key:
-        return key['keys']
-
-    # Individual JWK per RFC 7517
-    elif 'kty' in key:
-        return (key,)
-
-    # Some other mapping. Firebase uses just dict of kid, cert pairs
-    elif isinstance(key, Mapping):
-        values = key.values()
-        if values:
-            return values
-        return (key,)
+    if isinstance(key, Mapping):
+        if 'keys' in key:
+            # JWK Set per RFC 7517
+            return key['keys']
+        elif 'kty' in key:
+            # Individual JWK per RFC 7517
+            return (key,)
+        else:
+            # Some other mapping. Firebase uses just dict of kid, cert pairs
+            values = key.values()
+            if values:
+                return values
+            return (key,)
 
     # Iterable but not text or mapping => list- or tuple-like
     elif (isinstance(key, Iterable) and
-          not (isinstance(key, six.string_types) or isinstance(key, Mapping))):
+          not (isinstance(key, six.string_types) or isinstance(key, six.binary_type))):
         return key
 
     # Scalar value, wrap in tuple.

diff --git a/tests/test_jws.py b/tests/test_jws.py
index 2282c5f..4ca57a4 100644
--- a/tests/test_jws.py
+++ b/tests/test_jws.py
@@ -77,6 +77,17 @@ class TestJWS(object):
         with pytest.raises(JWSError):
             jws.sign(payload, 'secret', algorithm='RS256')
 
+    @pytest.mark.parametrize("key", [
+        b'key',
+        'key',
+    ])
+    def test_round_trip_with_different_key_types(self, key):
+        signed_data = jws.sign({'testkey': 'testvalue'}, key, algorithm=ALGORITHMS.HS256)
+        verified_bytes = jws.verify(signed_data, key, algorithms=[ALGORITHMS.HS256])
+        verified_data = json.loads(verified_bytes.decode('utf-8'))
+        assert 'testkey' in verified_data.keys()
+        assert verified_data['testkey'] == 'testvalue'
+
 
 class TestHMAC(object):
 
diff --git a/tests/test_jwt.py b/tests/test_jwt.py
index 03f5c28..03783ef 100644
--- a/tests/test_jwt.py
+++ b/tests/test_jwt.py
@@ -52,6 +52,13 @@ class TestJWT:
                 key=key,
                 algorithms=[])
 
+    @pytest.mark.parametrize("key, token",
+                             [('1234567890', u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCJ9.aNBlulVhiYSCzvsh1rTzXZC2eWJmNrMBjINT-0wQz4k'),
+                              ('123456789.0',u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCJ9.D8WLFPMi3yKgua2jm3BKThFsParXpgxhIbsUc39zJDw')])
+    def test_numeric_key(self, key, token):
+        token_info = jwt.decode(token, key)
+        assert token_info == {"name": "test"}
+
     def test_invalid_claims_json(self):
         old_jws_verify = jws.verify
         try:
@@ -165,6 +172,16 @@ class TestJWT:
 
         assert decoded == claims
 
+    @pytest.mark.parametrize('key', [
+        b'key',
+        'key',
+    ])
+    def test_round_trip_with_different_key_types(self, key):
+        token = jwt.encode({'testkey': 'testvalue'}, key, algorithm='HS256')
+        verified_data = jwt.decode(token, key, algorithms=['HS256'])
+        assert 'testkey' in verified_data.keys()
+        assert verified_data['testkey'] == 'testvalue'
+
     def test_leeway_is_int(self):
         pass
 

Various issues in jwt.decode / jws._get_keys
I've had a couple issues (figuring out how to use jwt.decode) which stem from the jws._get_keys implementation.

1. key argument must be iterable- raises exception otherwise
2. string key argument must not contain 'keys' (ie if a PEM base64 segment or HS secret segment contains keys, it'll break)
3. key can't be the result of calling jwk.construct (usability issue)
4. attempting json.loads on anything not a string seems weird



tests/test_jws.py::TestJWS::test_round_trip_with_different_key_types[key0] tests/test_jwt.py::TestJWT::test_numeric_key[1234567890-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCJ9.aNBlulVhiYSCzvsh1rTzXZC2eWJmNrMBjINT-0wQz4k] tests/test_jwt.py::TestJWT::test_numeric_key[123456789.0-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCJ9.D8WLFPMi3yKgua2jm3BKThFsParXpgxhIbsUc39zJDw] tests/test_jwt.py::TestJWT::test_round_trip_with_different_key_types[key0]
tests/test_jws.py::TestJWS::test_unicode_token tests/test_jws.py::TestJWS::test_multiple_keys tests/test_jws.py::TestJWS::test_invalid_algorithm tests/test_jws.py::TestJWS::test_not_enough_segments tests/test_jws.py::TestJWS::test_header_invalid_padding tests/test_jws.py::TestJWS::test_header_not_json tests/test_jws.py::TestJWS::test_claims_invalid_padding tests/test_jws.py::TestJWS::test_claims_not_json tests/test_jws.py::TestJWS::test_invalid_key tests/test_jws.py::TestJWS::test_round_trip_with_different_key_types[key1] tests/test_jws.py::TestHMAC::testHMAC256 tests/test_jws.py::TestHMAC::testHMAC384 tests/test_jws.py::TestHMAC::testHMAC512 tests/test_jws.py::TestHMAC::test_wrong_alg tests/test_jws.py::TestHMAC::test_wrong_key tests/test_jws.py::TestHMAC::test_unsupported_alg tests/test_jws.py::TestHMAC::test_add_headers tests/test_jws.py::TestGetKeys::test_dict tests/test_jws.py::TestGetKeys::test_custom_object tests/test_jws.py::TestGetKeys::test_RFC7517_string tests/test_jws.py::TestGetKeys::test_RFC7517_jwk tests/test_jws.py::TestGetKeys::test_RFC7517_mapping tests/test_jws.py::TestGetKeys::test_string tests/test_jws.py::TestGetKeys::test_tuple tests/test_jws.py::TestGetKeys::test_list tests/test_jws.py::TestRSA::test_jwk_set tests/test_jws.py::TestRSA::test_jwk_set_failure tests/test_jws.py::TestRSA::test_RSA256 tests/test_jws.py::TestRSA::test_RSA384 tests/test_jws.py::TestRSA::test_RSA512 tests/test_jws.py::TestRSA::test_wrong_alg tests/test_jws.py::TestRSA::test_wrong_key tests/test_jws.py::TestRSA::test_private_verify_raises_warning tests/test_jws.py::TestEC::test_EC256 tests/test_jws.py::TestEC::test_EC384 tests/test_jws.py::TestEC::test_EC512 tests/test_jws.py::TestEC::test_wrong_alg tests/test_jws.py::TestLoad::test_header_not_mapping tests/test_jws.py::TestLoad::test_claims_not_mapping tests/test_jws.py::TestLoad::test_signature_padding tests/test_jwt.py::TestJWT::test_no_alg tests/test_jwt.py::TestJWT::test_invalid_claims_json tests/test_jwt.py::TestJWT::test_invalid_claims tests/test_jwt.py::TestJWT::test_non_default_alg tests/test_jwt.py::TestJWT::test_non_default_alg_positional_bwcompat tests/test_jwt.py::TestJWT::test_no_alg_default_headers tests/test_jwt.py::TestJWT::test_non_default_headers tests/test_jwt.py::TestJWT::test_deterministic_headers tests/test_jwt.py::TestJWT::test_encode tests/test_jwt.py::TestJWT::test_decode tests/test_jwt.py::TestJWT::test_round_trip_with_different_key_types[key1] tests/test_jwt.py::TestJWT::test_leeway_is_int tests/test_jwt.py::TestJWT::test_leeway_is_timedelta tests/test_jwt.py::TestJWT::test_iat_not_int tests/test_jwt.py::TestJWT::test_nbf_not_int tests/test_jwt.py::TestJWT::test_nbf_datetime tests/test_jwt.py::TestJWT::test_nbf_with_leeway tests/test_jwt.py::TestJWT::test_nbf_in_future tests/test_jwt.py::TestJWT::test_nbf_skip tests/test_jwt.py::TestJWT::test_exp_not_int tests/test_jwt.py::TestJWT::test_exp_datetime tests/test_jwt.py::TestJWT::test_exp_with_leeway tests/test_jwt.py::TestJWT::test_exp_in_past tests/test_jwt.py::TestJWT::test_exp_skip tests/test_jwt.py::TestJWT::test_aud_string tests/test_jwt.py::TestJWT::test_aud_list tests/test_jwt.py::TestJWT::test_aud_list_multiple tests/test_jwt.py::TestJWT::test_aud_list_is_strings tests/test_jwt.py::TestJWT::test_aud_case_sensitive tests/test_jwt.py::TestJWT::test_aud_empty_claim tests/test_jwt.py::TestJWT::test_aud_not_string_or_list tests/test_jwt.py::TestJWT::test_aud_given_number tests/test_jwt.py::TestJWT::test_iss_string tests/test_jwt.py::TestJWT::test_iss_list tests/test_jwt.py::TestJWT::test_iss_tuple tests/test_jwt.py::TestJWT::test_iss_invalid tests/test_jwt.py::TestJWT::test_sub_string tests/test_jwt.py::TestJWT::test_sub_invalid tests/test_jwt.py::TestJWT::test_sub_correct tests/test_jwt.py::TestJWT::test_sub_incorrect tests/test_jwt.py::TestJWT::test_jti_string tests/test_jwt.py::TestJWT::test_jti_invalid tests/test_jwt.py::TestJWT::test_at_hash tests/test_jwt.py::TestJWT::test_at_hash_invalid tests/test_jwt.py::TestJWT::test_at_hash_missing_access_token tests/test_jwt.py::TestJWT::test_at_hash_missing_claim tests/test_jwt.py::TestJWT::test_at_hash_unable_to_calculate tests/test_jwt.py::TestJWT::test_bad_claims tests/test_jwt.py::TestJWT::test_unverified_claims_string tests/test_jwt.py::TestJWT::test_unverified_claims_list tests/test_jwt.py::TestJWT::test_unverified_claims_object tests/test_jwt.py::TestJWT::test_require[aud-aud] tests/test_jwt.py::TestJWT::test_require[ait-ait] tests/test_jwt.py::TestJWT::test_require[exp-value2] tests/test_jwt.py::TestJWT::test_require[nbf-value3] tests/test_jwt.py::TestJWT::test_require[iss-iss] tests/test_jwt.py::TestJWT::test_require[sub-sub] tests/test_jwt.py::TestJWT::test_require[jti-jti]