5454                        'service-accounts/default/email' )
5555
5656
57+ class  _EmulatedSigner (google .auth .crypt .Signer ):
58+     key_id  =  None 
59+ 
60+     def  __init__ (self ):
61+         pass 
62+ 
63+     def  sign (self , message ):
64+         return  b'' 
65+ 
66+ 
5767class  _SigningProvider :
5868    """Stores a reference to a google.auth.crypto.Signer.""" 
5969
@@ -78,6 +88,10 @@ def from_iam(cls, request, google_cred, service_account):
7888        signer  =  iam .Signer (request , google_cred , service_account )
7989        return  _SigningProvider (signer , service_account )
8090
91+     @classmethod  
92+     def  for_emulator (cls ):
93+         return  _SigningProvider (
_EmulatedSigner (), 
'[email protected] ' )
 94+ 
8195
8296class  TokenGenerator :
8397    """Generates custom tokens and session cookies.""" 
@@ -94,6 +108,8 @@ def __init__(self, app, http_client, url_override=None):
94108
95109    def  _init_signing_provider (self ):
96110        """Initializes a signing provider by following the go/firebase-admin-sign protocol.""" 
111+         if  _auth_utils .is_emulated ():
112+             return  _SigningProvider .for_emulator ()
97113        # If the SDK was initialized with a service account, use it to sign bytes. 
98114        google_cred  =  self .app .credential .get_credential ()
99115        if  isinstance (google_cred , google .oauth2 .service_account .Credentials ):
@@ -291,15 +307,15 @@ def verify(self, token, request):
291307            error_message  =  (
292308                '{0} expects {1}, but was given a custom ' 
293309                'token.' .format (self .operation , self .articled_short_name ))
294-         elif  not  header .get ('kid' ):
310+         elif  not  _auth_utils . is_emulated ()  and   not   header .get ('kid' ):
295311            if  header .get ('alg' ) ==  'HS256'  and  payload .get (
296312                    'v' ) ==  0  and  'uid'  in  payload .get ('d' , {}):
297313                error_message  =  (
298314                    '{0} expects {1}, but was given a legacy custom ' 
299315                    'token.' .format (self .operation , self .articled_short_name ))
300316            else :
301317                error_message  =  'Firebase {0} has no "kid" claim.' .format (self .short_name )
302-         elif  header .get ('alg' ) !=  'RS256' :
318+         elif  not   _auth_utils . is_emulated ()  and   header .get ('alg' ) !=  'RS256' :
303319            error_message  =  (
304320                'Firebase {0} has incorrect algorithm. Expected "RS256" but got ' 
305321                '"{1}". {2}' .format (self .short_name , header .get ('alg' ), verify_id_token_msg ))
@@ -329,6 +345,10 @@ def verify(self, token, request):
329345        if  error_message :
330346            raise  self ._invalid_token_error (error_message )
331347
348+         if  _auth_utils .is_emulated ():
349+             claims  =  jwt .decode (token , verify = False )
350+             claims ['uid' ] =  claims ['sub' ]
351+             return  claims 
332352        try :
333353            verified_claims  =  google .oauth2 .id_token .verify_token (
334354                token ,
0 commit comments