Search code examples
gofirebase-authenticationfirebase-admin

Import external user to firebase


I want to import users from an external database to firebase.

The password were hashed with a sha256 function with the password prepended by a salt (which is a UUID).

For example:

password = "123qwerty!"
salt = "cb60eb29-95a2-418e-be2a-c1c107fb1add"
hash = sha256(salt+password)
# 54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595

Now to import this to firebase I would do the following:

users = []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
    UID("some-uid").
    Email("jon.foo@example.com").
    PasswordHash([]byte("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")).
    PasswordSalt([]byte("cb60eb29-95a2-418e-be2a-c1c107fb1add")).
    DisplayName("Jon FOO"))

h := hash.SHA256{
    Rounds:     1,
    InputOrder: hash.InputOrderSaltFirst,
}
res, err := cl.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
    log.Fatal(err)
}

The user is well imported in firebase (I can see it in the console), but when I try to login, I have this error The password is invalid or the user does not have a password.

I cannot see what is wrong with my way, maybe the Rounds parameter should be updated, but to what value?

Thanks!


Solution

  • I finally found my issue. In my case I was giving as the PasswordHash the hex representation of the password:

    PasswordHash([]byte("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")).
    

    It turns out I have to decode first the password, like the following:

    decoded, err := hex.DecodeString("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")
    if err != nil {
        return err
    }
    user := (&auth.UserToImport{}).
        PasswordHash(decoded).
        PasswordSalt([]byte("cb60eb29-95a2-418e-be2a-c1c107fb1add")). // the salt stays the same
        ...
    
    // call ImportUsers with the same hash configuration (Rounds: 1, InputOrder: SaltFirst)
    

    After updating this I ran the code and I could now authenticate with my imported user.

    Quick note: as mentionned in the comment, the node SDK does not have the option to specify the input order (salt or password first), this seems to be an important missing feature.