5353METADATA_SERVICE_URL = ('http://metadata.google.internal/computeMetadata/v1/instance/'
5454 'service-accounts/default/email' )
5555
56+ # Emulator fake account
57+ AUTH_EMULATOR_EMAIL = '[email protected] ' 58+
59+
60+ class _EmulatedSigner (google .auth .crypt .Signer ):
61+ key_id = None
62+
63+ def __init__ (self ):
64+ pass
65+
66+ def sign (self , message ):
67+ return b''
68+
5669
5770class _SigningProvider :
5871 """Stores a reference to a google.auth.crypto.Signer."""
@@ -78,6 +91,10 @@ def from_iam(cls, request, google_cred, service_account):
7891 signer = iam .Signer (request , google_cred , service_account )
7992 return _SigningProvider (signer , service_account )
8093
94+ @classmethod
95+ def for_emulator (cls ):
96+ return _SigningProvider (_EmulatedSigner (), AUTH_EMULATOR_EMAIL )
97+
8198
8299class TokenGenerator :
83100 """Generates custom tokens and session cookies."""
@@ -94,6 +111,8 @@ def __init__(self, app, http_client, url_override=None):
94111
95112 def _init_signing_provider (self ):
96113 """Initializes a signing provider by following the go/firebase-admin-sign protocol."""
114+ if _auth_utils .is_emulated ():
115+ return _SigningProvider .for_emulator ()
97116 # If the SDK was initialized with a service account, use it to sign bytes.
98117 google_cred = self .app .credential .get_credential ()
99118 if isinstance (google_cred , google .oauth2 .service_account .Credentials ):
@@ -286,20 +305,22 @@ def verify(self, token, request):
286305 verify_id_token_msg = (
287306 'See {0} for details on how to retrieve {1}.' .format (self .url , self .short_name ))
288307
308+ emulated = _auth_utils .is_emulated ()
309+
289310 error_message = None
290311 if audience == FIREBASE_AUDIENCE :
291312 error_message = (
292313 '{0} expects {1}, but was given a custom '
293314 'token.' .format (self .operation , self .articled_short_name ))
294- elif not header .get ('kid' ):
315+ elif not emulated and not header .get ('kid' ):
295316 if header .get ('alg' ) == 'HS256' and payload .get (
296317 'v' ) == 0 and 'uid' in payload .get ('d' , {}):
297318 error_message = (
298319 '{0} expects {1}, but was given a legacy custom '
299320 'token.' .format (self .operation , self .articled_short_name ))
300321 else :
301322 error_message = 'Firebase {0} has no "kid" claim.' .format (self .short_name )
302- elif header .get ('alg' ) != 'RS256' :
323+ elif not emulated and header .get ('alg' ) != 'RS256' :
303324 error_message = (
304325 'Firebase {0} has incorrect algorithm. Expected "RS256" but got '
305326 '"{1}". {2}' .format (self .short_name , header .get ('alg' ), verify_id_token_msg ))
@@ -330,11 +351,14 @@ def verify(self, token, request):
330351 raise self ._invalid_token_error (error_message )
331352
332353 try :
333- verified_claims = google .oauth2 .id_token .verify_token (
334- token ,
335- request = request ,
336- audience = self .project_id ,
337- certs_url = self .cert_url )
354+ if emulated :
355+ verified_claims = payload
356+ else :
357+ verified_claims = google .oauth2 .id_token .verify_token (
358+ token ,
359+ request = request ,
360+ audience = self .project_id ,
361+ certs_url = self .cert_url )
338362 verified_claims ['uid' ] = verified_claims ['sub' ]
339363 return verified_claims
340364 except google .auth .exceptions .TransportError as error :
0 commit comments