0

I want to let the user log in by REST. My application sends me an emailaddress and a password, and I want Firebase to check whether that's a valid credential combination. Then a JWT is send back to the client to verify all requests.

However, the Firebase Admin SDK seems not to have a function like admin.auth.loginWithEmailAndPassword() or something. How can I log the user in completely server side?

The server is running on Cloud Functions for Firebase.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Jaap Weijland
  • 3,146
  • 5
  • 23
  • 31

2 Answers2

2

The normal approach for this would be to let the client validate the email/password and then send the resulting token to your server. That way the server can validate the token, instead of having to validate the credentials.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hello Frank, Is it still the same case now too? We want to pass user credentials to server and authenticate there. Earlier we used https://developers.google.com/identity/toolkit/migrate-identityplatform REST API through firebase cloud functions. But i see its deprecated now. Can you please suggest? – Ayyappa Aug 05 '19 at 07:35
  • The approach is still valid. The link to the documentation should still describe how to implement this, which uses the Admin SDK instead of a REST API. – Frank van Puffelen Aug 05 '19 at 14:12
  • Please post new questions as... new questions, not as comments to an existing question that is almost 2 years old. – Frank van Puffelen Aug 09 '19 at 17:30
  • Sure Frank. Here is the question - https://stackoverflow.com/questions/57391084/firebase-authentication-vs-google-identity-toolkit-pricing – Ayyappa Aug 10 '19 at 01:05
1

I did this a little differently. I have a cloud function that creates the user account calling createUser() which receives in all the information I want to add to the account both in Authentication and in Firestore. I throw HttpsError when accounts exists or there is a DB issue. When I return back to the front end, I then call signInWithEmailAndPassword to log user in on front end. This allows me to easily populate the account with data I want while keeping the method more secured in a function. I fully understand there are many ways to accomplish, just sharing what I did. Also note this code is NOT cleaned up nor are all errors properly caught yet. I am sure it could be greatly improved.

Firebase function:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
// http callable function createUser
exports.createUser = functions.https.onCall(async (data, context) => {
  const firstName = data.firstName;
  const lastName = data.lastName;
  const email = data.email;
  const password = data.password;
  await admin.auth().createUser({
    email: email,
    password: password,
    displayName: firstName + " " + lastName,
    disabled: false,
    customClaims: {roleId: 1},
  }).then(function(userRecord) {
      db.collection("users").doc(userRecord.uid).set({
      firstname: firstName,
      lastname: lastName,
    }).catch((err) => {
      console.log("Failure to save user in DB.  Error was " + err.message);
      throw new functions.https.HttpsError('already-exists','Unable to create account.  Contact support.');
    });
  }).catch(function(error) {
    console.log("Error creating new user in Authentication.  Error was ", error.message);
    throw new functions.https.HttpsError('already-exists','Email account already exists');
  });
  return "success";
});

My front end JavaScript

        const registerForm = document.querySelector('.register');    
        registerForm.addEventListener('submit', (e) => {
                e.preventDefault();
                const password = registerForm.password.value;
                const confirm = registerForm.confirm.value;
                if (password == confirm){
                    const firstName = registerForm.first_name.value;
                    const lastName = registerForm.last_name.value;
                    const email = registerForm.email.value;
                    const createUser = functions.httpsCallable('createUser');
                    const data = {
                        firstName: firstName,
                        lastName: lastName,
                        email: email,
                        password: password
                    };
                    createUser(data).then(response => {
                        // Now lets try to log the user in
    firebase.auth().signInWithEmailAndPassword(email,password).then(userRecord => {
                            console.log("successfully logged in " + email);
                        }).catch((err) => {
                            console.log("Failure to log in user.  Error was " + err.message);
                        });
                        // Do something here to manage UI
                    }).catch((e)=> {
                        console.log(e.message);
// Handle Errors in UI
                    });
                } else {
// Handle Errors in UI
                };
            });
kfansler
  • 11
  • 1