Create a client-side auth ID token from Python

1,634 views
Skip to first unread message

Alan deLespinasse

unread,
Nov 7, 2019, 3:13:25 PM11/7/19
to Firebase Google Group
Our Firebase app includes a backend server that serves REST-ish endpoints. The frontend app can include an ID token (obtained from user.getIdToken()) in calls to the backend, which authenticates the calls and returns 403 if it fails. Works great.

Now we have a separate Python program that needs to make calls as a client to that backend API. It's fine for the program to have a certificate for a service account (anyone using this code is a trusted employee). But the Python firebase-admin client library doesn't seem to have the equivalent of user.getIdToken().

How do I generate an ID token that can be included in the REST calls? I think the following would work:
  1. Call firebase_admin.auth.create_custom_token() to get a custom token (this can include "developer claims" which I assume are equivalent to "custom claims")
  2. Call the Exchange custom token for an ID and refresh token endpoint of the Firebase REST Auth API to get an ID and refresh token; store them for later use
  3. Each time it needs to make an API call to the backend, check whether the ID token has expired. If it hasn't, just include it with the API call. If it has expired, first call the Exchange a refresh token for an ID token endpoint of the Firebase REST API to get a fresh ID token, and use that.
Doesn't seem too hard, but it is harder than just calling user.getIdToken() from the front end.

(1) Will the above method work?
(2) Is there an easier way that I'm missing? (For example, does the Python firebase-admin client include something equivalent to steps 2 and 3 so I don't have to directly call the Firebase Auth REST endpoints?)

Hiranya Jayathilaka

unread,
Nov 7, 2019, 4:25:32 PM11/7/19
to fireba...@googlegroups.com
On Thu, Nov 7, 2019 at 12:13 PM Alan deLespinasse <adeles...@gmail.com> wrote:
Our Firebase app includes a backend server that serves REST-ish endpoints. The frontend app can include an ID token (obtained from user.getIdToken()) in calls to the backend, which authenticates the calls and returns 403 if it fails. Works great.

Now we have a separate Python program that needs to make calls as a client to that backend API. It's fine for the program to have a certificate for a service account (anyone using this code is a trusted employee). But the Python firebase-admin client library doesn't seem to have the equivalent of user.getIdToken().

How do I generate an ID token that can be included in the REST calls? I think the following would work:
  1. Call firebase_admin.auth.create_custom_token() to get a custom token (this can include "developer claims" which I assume are equivalent to "custom claims")
  2. Call the Exchange custom token for an ID and refresh token endpoint of the Firebase REST Auth API to get an ID and refresh token; store them for later use
  3. Each time it needs to make an API call to the backend, check whether the ID token has expired. If it hasn't, just include it with the API call. If it has expired, first call the Exchange a refresh token for an ID token endpoint of the Firebase REST API to get a fresh ID token, and use that.
Doesn't seem too hard, but it is harder than just calling user.getIdToken() from the front end.

(1) Will the above method work?

Yes, this will work. Check out the following integration test which essentially implements this (minus the ID token caching part): https://github.com/firebase/firebase-admin-python/blob/c6080e41a2817175704d0216d8173fb4ee983913/integration/test_auth.py#L89-L93 
 
(2) Is there an easier way that I'm missing? (For example, does the Python firebase-admin client include something equivalent to steps 2 and 3 so I don't have to directly call the Firebase Auth REST endpoints?)

No, the Admin SDK doesn't provide any user authentication operations at the moment.

Thanks,
Hiranya
 

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/1f1e1999-07f5-47f9-8256-620f067a7af8%40googlegroups.com.


--

Hiranya Jayathilaka | Software Engineer | h...@google.com | 650-203-0128

Alan deLespinasse

unread,
Nov 7, 2019, 5:53:28 PM11/7/19
to Firebase Google Group
Thanks!

What's up with the versioning of the auth REST endpoints? In the docs that I linked to above, the "Exchange custom token..." endpoint is at:


whereas in the test you linked to, it seems to be:


Are these equivalent?


On Thursday, November 7, 2019 at 4:25:32 PM UTC-5, Hiranya Jayathilaka wrote:
On Thu, Nov 7, 2019 at 12:13 PM Alan deLespinasse <adeles...@gmail.com> wrote:
Our Firebase app includes a backend server that serves REST-ish endpoints. The frontend app can include an ID token (obtained from user.getIdToken()) in calls to the backend, which authenticates the calls and returns 403 if it fails. Works great.

Now we have a separate Python program that needs to make calls as a client to that backend API. It's fine for the program to have a certificate for a service account (anyone using this code is a trusted employee). But the Python firebase-admin client library doesn't seem to have the equivalent of user.getIdToken().

How do I generate an ID token that can be included in the REST calls? I think the following would work:
  1. Call firebase_admin.auth.create_custom_token() to get a custom token (this can include "developer claims" which I assume are equivalent to "custom claims")
  2. Call the Exchange custom token for an ID and refresh token endpoint of the Firebase REST Auth API to get an ID and refresh token; store them for later use
  3. Each time it needs to make an API call to the backend, check whether the ID token has expired. If it hasn't, just include it with the API call. If it has expired, first call the Exchange a refresh token for an ID token endpoint of the Firebase REST API to get a fresh ID token, and use that.
Doesn't seem too hard, but it is harder than just calling user.getIdToken() from the front end.

(1) Will the above method work?

Yes, this will work. Check out the following integration test which essentially implements this (minus the ID token caching part): https://github.com/firebase/firebase-admin-python/blob/c6080e41a2817175704d0216d8173fb4ee983913/integration/test_auth.py#L89-L93 
 
(2) Is there an easier way that I'm missing? (For example, does the Python firebase-admin client include something equivalent to steps 2 and 3 so I don't have to directly call the Firebase Auth REST endpoints?)

No, the Admin SDK doesn't provide any user authentication operations at the moment.

Thanks,
Hiranya
 

--
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 fireba...@googlegroups.com.

Hiranya Jayathilaka

unread,
Nov 7, 2019, 6:07:25 PM11/7/19
to fireba...@googlegroups.com
I expect them to be equivalent, with the latter just being a newer version of the same API.

To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/3b7b867e-c8d9-448c-b5a1-db16486973d5%40googlegroups.com.

Alan deLespinasse

unread,
Nov 11, 2019, 2:44:45 PM11/11/19
to Firebase Google Group
So that means the official docs still show v1 even though v3 existed at least a year and a half ago (according to blame)?
Reply all
Reply to author
Forward
0 new messages