How do i get currentUser in firebase admin SDK. In client SDK we can use
onAuthStateChanged() or firebase.auth().currentUser()
In NodeJs Server.js file firebase admin SDK onAuthStateChanged() Do not work, what should work here?
Basically i want only logged in users to access my innerPages so i am using express,nodejs app.get method to create routes.
app.get('/', authenticationRequired ,function(req,res){
res.sendFile(path.join(__dirname+'/index.html'));
});
And trying to write authenticationRequired method (returns false or true depending on if user is logged in).
The Firebase Admin SDK does not inherently know what user is using your Express web app. You will need to implement code for this. If you're already using Firebase Authentication in the web app, this takes these steps:
Retrieve the user's ID token on the client
You can get a user's ID token by using the firebase.auth().currentUser.getIdToken() method.
Pass this token from the client to the server
Verify the token on the server
The user ID token can be verified using the admin.auth().verifyIdToken(idToken) method. On success it will return a promise with the decodedToken, otherwise it will return a rejected promise.
Related
I'm trying to secure my firebase functions by using authorization.
I wrote a very simple callable function
exports.hey= functions.https.onCall((data, context) => {
return {hello:"world"};
});
then i deployed to GC and add the permission invoker to allAuthenticatedUsers .
then i went to my app and wrote some test code
FirebaseFunctions.getInstance().getHttpsCallable("hey").call(null).addOnCompleteListener(task -> {
if (task.isSuccessful())
System.out.println(task.getResult().getData());
else
FirebaseCrashlytics.getInstance().recordException(task.getException());
});
This code runs after user authenticateFirebaseAuth.getInstance().signInWithCustomToken(); (I've my own authentication system it works I can see the authenticated user in firebase auth dashboard along with last login the user is able to read database) but the function call always returns http 403
I know that within the function i can use the context to check the auth field and verify if user is authenticated, but what is the point of the permissioning system at all in the GC? if at the end we always need to check the context.auth am i missing something?
W/System.err: com.google.firebase.functions.FirebaseFunctionsException: UNAUTHENTICATED
If the ID token passed to a Cloud Function represents a Google account it works, otherwise, it doesn't.
An authenticated client request for a Google Cloud Functions must have an Authorization: Bearer ID_TOKEN header or ?access_token=ID_TOKEN.
The Authentication header is set with the user’s ID token which is used as a context parameter. A Firebase user’s ID token doesn’t always represent a Google user which makes it incompatible with allAuthenticatedUsers. Because of this you check context.auth. Otherwise you may try with “allUsers” which should work.
You can see this stackoverflow answer for more information.
I've got an api where I validate an idToken from firebase, this api is used by a web app and a mobile app.
The web app uses a session token and the mobile app the standard idToken.
As it stands my api correctly validates the standard token from the mobile app using the admin sdk's admin.auth().verifyIdToken() method.
If I pass the session token to this it fails with an iss error
Firebase ID token has incorrect "iss" (issuer) claim
I know I can validate the session token via
admin.auth().verifySessionCookie() method. But I would have to do this in the catch block of the verifyIdToken promise.
Is there a method or way where I can just use one step to validate this token, or is my only option to catch an error from one and then try the other method?
I am working to implement a Node.js webapp to be deployed on GCP App Engine.
Following the Node.js Bookshelf App sample, I did manage to implement a basic user authentication flow using the passport-google-oauth20 and retrieve basic profile information. I basically just got rid of what was not needed for my purposes
My custom code is available at: gist.github.com/vdenotaris/3a6dcd713e4c3ee3a973aa00cf0a45b0.
However, I would now like to consume a GCP Cloud Storage API to retrieve all the storage objects within a given buckets with the logged identity.
This should be possible by:
adding a proper scope for the request.
authenticating the REST requests using the user session token obtained via OAuth.
About the post-auth handler, the documentation says:
After you obtain credentials, you can store information about the
user. Passport.js automatically serializes the user to the session.
After the user’s information is in the session, you can make a couple
of middleware functions to make it easier to work with authentication.
// Middleware that requires the user to be logged in. If the user is not logged
// in, it will redirect the user to authorize the application and then return
// them to the original URL they requested.
function authRequired (req, res, next) {
if (!req.user) {
req.session.oauth2return = req.originalUrl;
return res.redirect('/auth/login');
}
next();
}
// Middleware that exposes the user's profile as well as login/logout URLs to
// any templates. These are available as `profile`, `login`, and `logout`.
function addTemplateVariables (req, res, next) {
res.locals.profile = req.user;
res.locals.login = `/auth/login?return=${encodeURIComponent(req.originalUrl)}`;
res.locals.logout = `/auth/logout?return=${encodeURIComponent(req.originalUrl)}`;
next();
}
But I do not see where the token is stored, how can I retrieve it and how to use it to consume a web-service (in my case, GCP storage).
I am not at all a node.js expert, so it would be nice having a bit more clarity on that: could someone explain me how to proceed in consuming a REST API using the logged user credentials (thus IAM/ACL privileges)?
If you want to access Cloud Storage through the use of a token obtained with OAuth, when the application requires user data, it will prompt a consent screen, asking for the user to authorize the app to get some of their data. If the user approves, an access token is generated, which can be attached to the user's request. This is better explained here.
If you plan to run your application in Google App Engine, there will be a service account prepared with the necessary authentication information, so no further setup is required. You may need to generate the service account credentials (generally in JSON format), that have to be added to the GOOGLE_APPLICATION_CREDENTIALS environment variable in gcloud.
Here is an example of how to authenticate and consume a REST API with the token that was obtained in the previous step. This, for example, would be a request to list objects stored in a bucket:
GET /storage/v1/b/example-bucket/o HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer [YOUR_TOKEN]
I have created an App using the Parse server, and have now decided to implement some aspects of firebase into my app. Im trying to accomplish this by doing the signInWithCustomToken method in swift on ios. Im calling a rest service to generate a firebase token, and then signing in with that token returned upon valid sign in on my current auth system. However, the token being generated appears to have an invalid signature when pasting it into jwt.io. The environment that im using is node based (inside the parse server). It seems very simple and i have followed the firebase instrucutions/poured over questions on this over the last few days and im really not sure what im doing wrong! Heres my rest service on how i generate the token, i initialize the server with this method:
Parse.Cloud.define("initServer", function(request, response){
var admin = require('firebase-admin');
var serviceAccount = require('/home/bitnami/apps/parse/htdocs/firebase/serviceAccountKey.json');
console.log(serviceAccount);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://urabo-acb7a.firebaseio.com'
});
response.success("Server Init OK");
});
this is the post method i call to generate the token from firebase-admin sdk:
Parse.Cloud.define("generateFirebaseToken", function(request, response) {
var admin = require('firebase-admin');
admin.auth().createCustomToken(request.params.uid)
.then(function(customToken) {
// Send token back to client
response.success(customToken);
})
.catch(function(error) {
console.log("Error creating custom token:", error);
});
});
And of course I went into the firebase console and generated the private key, and then scp'd it over to my server. Im not really sure why this is not working, it generates a token it just doesnt appear to be valid or linked to my account. Am i missing some weird encoding issue or something with the token? Does anyone have insight on this?? Thanks so much!
—The main question is are your users signing in to the REST service through your app and then you are also trying to re-authenticate them again with the token generated in your system?
—If they will be accessing further REST functions once authenticated, then why not authenticate them successfully when 'a' token is returned?
—Usually token usage or handling is restricted by the API providers. Another option is instead of involving user auth directly with the API service, have a separate auth system — the usual SignIn process and then make API calls based on the requested API feature. That way your app is interacting with the APIs and users remain at the front end.
I would like to authenticate and keep sessions via NodeJS with Firebase. Client can't directly communicate with Firebase.
In short:
Client (browser) <----> NodeJs(firebase-admin) <----> Firebase
I created Firebase client in NodeJS, then I used login method:
var firebaseClient = require('firebase');
firebaseClient.initializeApp(config)
firebaseClient.auth().signInWithEmailAndPassword(req.body.email, req.body.password).catch(function(error){
console.log(error);
})
and then I created route to check authenticated user:
app.get('/check',function(req,res){
var user = firebaseClient.auth().currentUser
console.log(user)
})
This method only allows me keep 1 previously logged user.
I would like to use firebase-admin, but I don't know how to keep session and authenticate users
You can authenticate clients on their respective devices/browsers using the client SDK, and them get them to send an ID token to a backend service written using firebase-admin (the admin SDK). The admin SDK provides methods for validating ID tokens sent by clients: https://firebase.google.com/docs/auth/admin/verify-id-tokens