Перенос бэкэнда Python из Gitkit в Firebase-Auth с python-jose для проверки токена
На GitHub полезный разработчик Google сказал мне, что
чтобы создать сеанс пользователя, вашему фоновому серверу Python требуется только библиотека JWT для проверки токена Firebase Auth (подписи и аудитории) в запросе и извлечения информации о пользователе из полезной нагрузки токена.
У меня проблемы с проверкой токена.
Это где я нахожусь; Чтобы начать миграцию, я сделал следующее:
Я добавил Firebase-Auth в приложение для Android, оставив Gitkit в приложении до тех пор, пока не будет работать Firebase-Auth. Теперь у меня есть две кнопки входа, одна для входа в Firebase, а другая для "почти устаревшего" Gitkit.
На firebase.com я импортировал проект Google в новый проект Firebase, поэтому база данных пользователей такая же. Мне уже удалось использовать Firebase-Auth в приложении для Android, я могу войти в систему как известный пользователь, и я могу успешно получить токен, который мне понадобится для моего внутреннего сервера, вызвав
mFirebaseAuth.getCurrentUser().getToken(false).getResult().getToken()
, Он содержит то же самоеuser_id
в качестве токена GitKit.
Сейчас я пытаюсь заменить identity-toolkit-python-client
библиотека с python-jose
, Поскольку в настоящее время я не отправляю токен Firebase на сервер, а только токен Gitkit, я хочу проверить это python-jose
библиотека на токене Gitkit.
На бэкэнд, перед звонком GitKit.VerifyGitkitToken()
я сейчас распечатываю результаты jose.jwt.get_unverified_header()
а также jose.jwt.get_unverified_claims()
чтобы проверить, смогу ли я увидеть то, что ожидаю. Результаты хорошие, я могу просматривать содержимое токена Gitkit так, как ожидалось.
Моя проблема связана с проверкой. Я не могу использовать jose.jwt.decode()
для проверки, потому что я не знаю, какой ключ мне нужно использовать.
jose.jwt.decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None)
Я знаю алгоритм из заголовка, и поле 'aud' также хранится в формулах, если это поможет.
Возвращаясь к комментариям инженеров
проверить токен Firebase Auth (подпись и аудитория)
Как мне сделать это с информацией, имеющейся у меня? Я предполагаю, что аудитория - это поле "aud" в заявках, но как мне проверить подпись?
После удаления зависимости Gitkit от сервера я продолжу миграцию.
Из того, что я видел, библиотека GitKit, очевидно, выполняет RPC-вызов на сервер Google для проверки, но я могу ошибаться.
Итак, какой будет ключ для проверки токена Gitkit, а также для проверки токена Firebase?
1 ответ
Ключи можно получить
для Firebase в https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com
и для Gitkit в https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys
Использование Googles oauth2client
библиотека делает проверку очень простой.
Но если вы хотите использовать python-jose
вместо oauth2client
затем вам нужно сначала преобразовать сертификат PEM в открытый ключ RSA (обновление: эта проблема исправлена, для Firebase эта проблема теперь обрабатывается библиотекой, прокрутите вниз до конца ссылку GitHub, предшествующую этому комментарию. Не уверен насчет Gitkit). Этот открытый ключ является ключом, который необходимо использовать. И аудиторию не следует извлекать из заголовка JWT, а жестко закодировать в исходный код, где в Firebase аудитория - это идентификатор проекта, а в Gitkit - один из идентификаторов клиента OAuth 2.0, который можно найти в консоли разработчика Google. Раздел учетных данных.
kid
в заголовке JWT используется для выбора соответствующего сертификата, который будет использоваться для получения ключа, используемого для выполнения проверки.
# firebase
# target_audience = "firebase-project-id"
# certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com'
# gitkit
target_audience = "123456789-abcdef.apps.googleusercontent.com" # (from developer console, OAuth 2.0 client IDs)
certificate_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys'
response = urllib.urlopen(certificate_url)
certs = response.read()
certs = json.loads(certs)
print "CERTS", certs
print ''
print ''
# -------------- verify via oauth2client
from oauth2client import crypt
crypt.MAX_TOKEN_LIFETIME_SECS = 30 * 86400 # according to https://github.com/google/identity-toolkit-python-client/blob/master/identitytoolkit/gitkitclient.py
print "VALID TOKEN", crypt.verify_signed_jwt_with_certs(idtoken, certs, target_audience)
print ''
print ''
# -------------- verify via python-jose
from jose import jwt
unverified_header = jwt.get_unverified_header(idtoken)
print "UNVERIFIED HEADER", unverified_header
print ''
print ''
unverified_claims = jwt.get_unverified_claims(idtoken)
print "UNVERIFIED CLAIMS", unverified_claims
print ''
print ''
from ssl import PEM_cert_to_DER_cert
from Crypto.Util.asn1 import DerSequence
pem = certs[unverified_header['kid']]
der = PEM_cert_to_DER_cert(pem)
cert = DerSequence()
cert.decode(der)
tbsCertificate = DerSequence()
tbsCertificate.decode(cert[0])
rsa_public_key = tbsCertificate[6]
print "VALID TOKEN", jwt.decode(idtoken, rsa_public_key, algorithms=unverified_header['alg'], audience=target_audience)