How to share Authentication token between app in Firebase 3.0? - firebase

In older version of Firebase we can obtain authenticated token for sharing between our app, extensions.
But when upgrade to Firebase 3.0, that function doesn't work anymore.
I've use getTokenWithCompletion: on FIRUser, then in my App Extension I call signInWithCustomToken:completion: with token i just obtained. But Firebase return an error with messgage:
Error Domain=FIRAuthErrorDomain Code=17000 "The custom token format is
incorrect. Please check the documentation." UserInfo=0x799b6010
{error_name=ERROR_INVALID_CUSTOM_TOKEN, NSLocalizedDescription=The
custom token format is incorrect. Please check the documentation.}
How to get authenticate token from FIRUser to re-authenticate it in my App Extension?

signInWithCustomToken is meant to be used with your own tokens minted on your own server (read more here).
The best way for you to bootstrap a session between different components of your application will be to, at sign-in time, share the user's credential and perform the bootstraping across all your components.
For example, if you are using Facebook login, when your retrieve the facebook access token, you would have to share it from your app to your extension, and then call signInWithCredential with the same token in both your main app and extension.
There is currently no way to sign in a user into a Firebase app with the v3.X SDKs from another Firebase app instance.

I had the same problem this morning when upgrading to the latest version of Firebase on Android.
To fix the problem I had to update the Firebase Server SDK to version 3.0+
This is a Java backend implementation, but the same applies for NodeJS as well.
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-server-sdk</artifactId>
<version>[3.0.0,)</version>
</dependency>
In the new Firebase Server SDK you have to initialize your Firebase app first using a generated JSON file.(Found under permissions in your new Firebase console) Then you can generate the JWT token.
FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount(new FileInputStream("path/to/json/file.json"))
.setDatabaseUrl("https://myapp.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
String token = FirebaseAuth.getInstance().createCustomToken("userID");
A token generated this way worked allowed me to use the new signInWithCustomToken() method.
You can read more here: https://firebase.google.com/docs/auth/server
Hope this helps

I had the same error as the OP. I am assuming that you are using a service account email and private key during token generation on your server. The token my server generated was successful on http://jsfiddle.net/firebase/XDXu5/. However, my app would give the same error.
In the end, it turned out that I was signing it using "HS256" (which is what I was using in my existing token generation - pre firebase 3.0). When I changed it to "RS256" instead, the token generated works in the app.
Hope that helps.

Related

Firebase app_check, play integrity does not return a valid JWT token

We are trying to validate app check token sent from an app on a custom backend.
It works on the web and on android when using the safetyNet provider. However once the playIntegrity provider is used, the token returned by firebase app check is no longer a valid JWT. It's much shorter, like this: eyJlcnJvciI6ILVOS05QV05fRVJST1IifQ== which seems to be HS256 encoded.
The admin node sdk api seems that it does not allow for such token as can be seen here:
https://github.com/firebase/firebase-admin-node/blob/master/src/app-check/token-verifier.ts#L115

How to authenticate user to Firestore Go SDK?

I'm trying to use the Firestore Go SDK from a client application. This looks like a client-side SDK, based on the functions, but that might be my first error?
I'm struggling to authenticate the user to Firestore. I've already logged them in using the REST API for Firebase Auth. This returns me an ID token, refresh token, etc. How do I use this with the Firestore SDK?
The docs suggest I need to call firestore.NewClient(<context>, <project-id>, <option>). For the latter argument, I've tried option.WithCredentialsJSON(...) passing a JWT-decoded ID token. I've also tried passing the raw refresh token. In both cases, the SDK complains about what I'm passing.
How can I authenticate the user based on the tokens I've obtained?
The Go SDK for Firestore is meant to be used in a trusted environment, such as your development machine, a server you control, or Cloud Functions. It doesn't have a way to sign the user of the application in, but instead authenticates itself with the server with administrative credentials, which you'll don't want to have on non-trusted devices.
option.WithCredentialsJSON accepts not JWT token, but Google Application Default Credentials.
Other option is to provide path to the file with Google Application Default Credentials using environment variable GOOGLE_APPLICATION_CREDENTIALS since firebase sdk is a part of the cloud.google.com/go sdk.
Check out the examples (also with other options).
https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-go
https://godoc.org/cloud.google.com/go#example-package--ApplicationDefaultCredentials

Couldn't find my Api-key in my firebase console for my flutter project sign-up authentication

I'm new to flutter and trying to implement sign-up authentication in flutter using Firebase. But the problem is that when i learned about authentication, they provided a post method url which must accept API-KEY in it.
Now, i dont know where does my API-KEY exists.
http.post(https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=[API-KEY]');
You'll find it in Project Settings under the General tab.
If you add a web app, it's also the first parameter in the config.

sign in with slack and validate request from firebase backend for the angular app

i have built a webapp using angular material and firebase functions + realtime DB as the backend. I am using slack "Sign in with Slack" API oauth flow. All works well and i am able to generate a accessToken in the backend which i can store against the user in the realtime DB. Once that is done i make a redirect call to my angular app on the dashboard page. Currently i am passing userid in the redirect url which i use to drive user to dashboard and show his data.
This functionally works fine but is a big security issue. As i can directly type the redirect url and boom. I am in the dashboard.
So, how do i solve this? What should i be doing in the url redirect that is secure and validates the response is the the result of a valid request?
I am not familiar with the Slack OAuth SDK but in general, this is true for all OAuth providers. Ideally, at the point where you redirect to your callback URL with the slack authorization code and you exchange the auth code for a Slack access token before returning that access token to the client, you call the Slack API to get the Slack user ID with the access token and then mint a Firebase custom token with that uid. You then return that custom token to the client and signInWithCustomToken. Make sure you are checking the state field (which you set when started the Slack sign in) along with Auth code to verify that the flow started and ended on the same device.

Reusing the firebase-server-sdk credentials with the REST API

In the old version of Firebase, my server app written in Java would authenticate with my backend using the secret and the JWT token generator. Then, at anytime, I could call Firebase.getAuth().getToken() and reuse that token in an HTTP call as the auth parameter.
With the new firebase-server-sdk, how would I reuse my limited service account credentials / token with the REST API?
Map<String, Object> auth = new HashMap<String, Object>();
auth.put("uid", "server-app");
FirebaseOptions options = new FirebaseOptions.Builder()
.setDatabaseUrl(Environment.FIREBASE_URL)
.setServiceAccount(MyClass.class.getResourceAsStream("/keys/dev.json"))
.setDatabaseAuthVariableOverride(auth)
.build();
FirebaseApp.initializeApp(options);
That all works great when I use the SDK to subscribe / write to certain locations - specifically locations that require a server-app uid. But I use REST in conjunction in my server app, because I want my server app to make synchronous reads, something Firebase only supports through the REST API.
FirebaseRestClient firebaseRest = new RestAdapter.Builder()
.setEndpoint(Environment.FIREBASE_URL)
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(final RequestFacade request) {
request.addQueryParam("access_token", FirebaseAuth.getInstance().createCustomToken("server-app"));
}
})
.build().create(FirebaseRestClient.class);
I've tried adding both the access_token and auth param. It seems like that createCustomToken method produces a valid JWT, but the REST API isn't responding.
When I pass in that createCustomToken return value as the auth param, I get the following message:
"error" : "Missing claim 'kid' in auth header."
When I pass in that createCustomToken return value as the access_token param, I get the basic Permission denied API response.
Is there an easy way to reuse my existing firebase-server-sdk credentials in a REST API call?
The token you're attempting to use is a Firebase Authentication ID token - the type which is designed to be passed to the Firebase SDK on a client. The REST API accepts a Firebase access token (just like the ones in previous Firebase clients).
Your authentication is failing because normally the Firebase SDK takes care of turning your ID token into an access token. Your server can not do this transition or generate an access token using the Firebase SDK so I recommend using the original Firebase Token Generator library with your Firebase Secret to create access tokens for the REST API. This will work fine even for new Firebase projects created since the I/O release.
Note: In the Console your Database Secret can be found under (Gear Icon) > Project Settings > Database.
I'm sure this is not advised, given the name of the undocumented property, but...
If your SDK has logged in with a serviceAccount, you can use firebase.auth().INTERNAL.getToken(), which returns a promised accessToken (and expirationTime) which then works with the ?access_token parameter.

Resources