Custom tokens using a third-party Python JWT library

879 views
Skip to first unread message

Fabián Cuesta

unread,
Jul 11, 2016, 10:52:22 AM7/11/16
to Firebase Google Group
Hi

Since last week our custom tokens stop working in our iOS, Android, Web and REST clients. Did you change something regarding this feature?

We are using Python in our server to generate the custom tokens with the pyjwt lib. We also try the python-jose.

We try creating a new service account key with no success. Also a new hole service account with a new key, same result.

With pyjwt we get {"error" : "Missing claim 'kid' in auth header."} in the REST call

With python-jose we get {"error" : "Failed to validate signature."} in the REST call

Both samples, in iOS returns: Firebase error: Error Domain=FIRAuthErrorDomain Code=17000 "The custom token format is incorrect. Please check the documentation." UserInfo={NSLocalizedDescription=The custom token format is incorrect. Please check the documentation., error_name=ERROR_INVALID_CUSTOM_TOKEN}

Both samples, in Android returns: {com.google.firebase.auth.FirebaseAuthInvalidCredentialsException@830042447864} "com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The custom token format is incorrect. Please check the documentation."


Here is the code using pyjwt:

import logging
import traceback
import time
import Crypto.PublicKey.RSA as RSA
import jwt
import datetime

def create_token(uid, email, key):
try:
payload = {'alg': 'RS256',
'iss': email,
'sub': email, 
'iat': int(time.time()),
'exp': int(time.time()) + (60 * 60),
'uid': uid}
token = jwt.generate_jwt(payload, RSA.importKey(key), 'RS256', datetime.timedelta(minutes=5))
return token
except Exception as e:
logging.error("JWT create_token Error")
logging.error(e.message)
logging.error(traceback.format_exc())
return None

Here is the code using python-jose:

import logging
import traceback
from jose import jwt
import time

def create_token(uid, email, key):
try:
payload = {'alg': 'RS256',
'iss': email,
'sub': email, 
'iat': int(time.time()),
'exp': int(time.time()) + (60 * 60),
'uid': uid}
header = {'kid': 'd1cd6b7397f2c81e19b0d83ac8bf685db6dc27ca'}
token = jwt.encode(payload, key, algorithm='RS256', headers=header)
return token
except Exception as e:
logging.error("JWT create_token Error")
logging.error(e.message)
logging.error(traceback.format_exc())
return None


Thanks

Fabian

Jacob Wenger

unread,
Jul 11, 2016, 9:28:46 PM7/11/16
to fireba...@googlegroups.com
Hey Fabian,

Have you given our server auth docs a full read and do you understand how the auth flow is supposed to work on the server? How exactly are you using the custom tokens you generate?

In general, you create custom tokens using the instructions here and then exchange that token on a client for an ID token. Is that what you are doing? If you just want to use the REST API, you can try the instructions explain in this Stack Overflow post.

I'm happy to help you debug this issue, but I just need some more information from your end of which tokens you are trying to use where. We haven't made any changes recently which should affect tokens. However, note that custom tokens do expire after one hour, so make sure you are not using expired tokens.

Cheers,
Jacob

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/1f4d4641-dbaa-4c94-a2c6-7e88e911cf74%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Fabián Cuesta

unread,
Jul 12, 2016, 11:18:44 AM7/12/16
to Firebase Google Group
Hey Jacob

Thanks a lot for your reply.

We are using custom tokens to authenticate clients with against our servers, and give them access to a Firebase Database. This clients are in iOS, Android and Web clients.

We did change the custom token generation using the node server integration, and the clients are responding fine, but it will be nice to make work the python script as we had it working before. Forget about the REST samples.

Thanks


Fabian
header = {'kid': 'd1cd6b7397f2c81e19b0d83ac8bf685db6dc27ca'}
token = jwt.encode(payload, key, algorithm='RS256', headers=header)
return token
except Exception as e:
logging.error("JWT create_token Error")
logging.error(e.message)
logging.error(traceback.format_exc())
return None


Thanks

Fabian

Jacob Wenger

unread,
Jul 12, 2016, 7:42:20 PM7/12/16
to fireba...@googlegroups.com
Hey Fabian,

Thanks for the follow up. You can create a custom token using Python using the instructions here. You will have to do some work yourself and use a third-party JWT library like pyjwt since we don't have an official Firebase SDK for Python yet.

Cheers,
Jacob

header = {'kid': 'd1cd6b7397f2c81e19b0d83ac8bf685db6dc27ca'}
token = jwt.encode(payload, key, algorithm='RS256', headers=header)
return token
except Exception as e:
logging.error("JWT create_token Error")
logging.error(e.message)
logging.error(traceback.format_exc())
return None


Thanks

Fabian

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/1f4d4641-dbaa-4c94-a2c6-7e88e911cf74%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.

Fabián Cuesta

unread,
Jul 13, 2016, 10:58:34 AM7/13/16
to Firebase Google Group
Hi Jacob

As I told in my original post, we did follow those instructions and we were generating the custom token with no problems (please check our code). But since last week the iOS, Android and Web clients start returning "The custom token format is incorrect".

That is the reason of the post. 

Regards


Fabian
header = {'kid': 'd1cd6b7397f2c81e19b0d83ac8bf685db6dc27ca'}
token = jwt.encode(payload, key, algorithm='RS256', headers=header)
return token
except Exception as e:
logging.error("JWT create_token Error")
logging.error(e.message)
logging.error(traceback.format_exc())
return None


Thanks

Fabian

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/1f4d4641-dbaa-4c94-a2c6-7e88e911cf74%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Cordelia Link

unread,
Jul 14, 2016, 2:14:21 PM7/14/16
to Firebase Google Group
The "Missing claim 'kid' in auth header" error sounds like it's coming from the RT database, not the custom token auth endpoint. Can you provide more details about your REST calls? Specifically, are you calling signInWithCustomToken() in your client app as specified here?

Fabián Cuesta

unread,
Jul 14, 2016, 5:57:41 PM7/14/16
to Firebase Google Group
Hi Cordelia

Please, forget about the REST.

We are using signInWithCustomToken in ios, android and web clients.

Regards

Fabian

Jacob Wenger

unread,
Jul 15, 2016, 4:46:23 AM7/15/16
to fireba...@googlegroups.com
Hey Fabian,

Can you paste one of the custom tokens you generate into https://jwt.io/ and share the decoded payload here? That may give us some insight into what is going wrong. A few things you should also confirm:
  • Make sure the service account and project ID you are using to create your custom token corresponds to the Firebase project your clients are trying to authentication to.
  • Make sure the custom token is not expired.
  • Make sure the email and key you pass in are correct. email should be your service account's client_email and key should be your service account's private_key.
It looks like your first sample uses python-jwt, not pyjwt. I would give pyjwt a shot since it has the simplest API (in my opinion). Looking at your code, it seems weird that you are including the algorithm twice and the expiration time twice (with different values). Maybe that is what is causing the issue? Looking at the decoded token will help us figure out what is going wrong.

Cheers,
Jacob

Fabian


Thanks

Fabian

Fabián Cuesta

unread,
Jul 15, 2016, 11:26:27 AM7/15/16
to Firebase Google Group
Thanks a lot Jacob.

Can I send you the custom token in a secure way, without posting it here?

Thanks

Fabian
Fabian


Thanks

Fabian

Kato Richardson

unread,
Jul 15, 2016, 11:29:45 AM7/15/16
to Firebase Google Group

Hi Fabian, you can create a token with an expiration in the past to share. Unless you've added sensitive data, there's nothing in the decoded token more valuable than the user ID.


Fabian


Thanks

Fabian

Kato Richardson

unread,
Jul 15, 2016, 11:32:30 AM7/15/16
to Firebase Google Group

Sorry, was still typing. For decoded tokens specifically, you can omit sensitive data or send them via https://firebase.google.com/support/

Jacob Wenger

unread,
Jul 16, 2016, 10:35:08 AM7/16/16
to fireba...@googlegroups.com
Hey Fabian,

As Kato alluded to, the JWT payload isn't secret and the JWT itself expires in an hour. Regardless, you can email it to me privately at ja...@firebase.com if that makes you feel more comfortable. I'll report back here when we've figured out the problem. 

Cheers,
Jacob
Reply all
Reply to author
Forward
0 new messages