I have written a Google Cloud Function Express app and a command-line tool that uses Node.js on my local Mac.
Calling myclitool login
, a one-time prompt asks the user for their email and password. The CLI tool sends the email and password inside the request body using an HTTP POST request to the Express server, over SSL.
The server will send back a private API Key (generated by a trigger function at the time the user was registered) that will be written to ~/.myclitoolrc
and will be used for all subsequent calls to my API endpoint.
Each subsequent call from the CLI tool will lookup the private API Key in the Firestore accounts collection, and authenticate on per API call basis.
admin.firestore()
.collection('accounts')
.where('privateApiKey', '==', privateApiKey)
.get() // and so on
So far, the following code will locate the admin.auth.UserRecord
.
Service.prototype.signin = function signin(email, password) {
return new Promise(function(resolve, reject) {
admin.auth().getUserByEmail(email)
.then(userRecord => {
console.log(userRecord);
resolve('some value later');
})
.catch(err => {
reject(err);
});
});
};
The Firebase documentation says: https://firebase.google.com/docs/reference/admin/node/admin.auth.UserRecord
passwordHash (string or null)
The user’s hashed password (base64-encoded), only if Firebase Auth hashing algorithm (SCRYPT) is used. If a different hashing algorithm had been used when uploading this user, as is typical when migrating from another Auth system, this will be an empty string. If no password is set, this will be null. This is only available when the user is obtained from listUsers().
passwordSalt (string or null)
The user’s password salt (base64-encoded), only if Firebase Auth hashing algorithm (SCRYPT) is used. If a different hashing algorithm had been used to upload this user, typical when migrating from another Auth system, this will be an empty string. If no password is set, this will be null. This is only available when the user is obtained from listUsers().
The UserRecord is retrieved and contains the SCRYPTd passwordHash
and passwordSalt
properties.
UserRecord {
uid: 'kjep.[snip]..i2',
email: '[email protected]',
emailVerified: false,
displayName: undefined,
photoURL: undefined,
phoneNumber: undefined,
disabled: false,
metadata:
UserMetadata {
creationTime: 'Thu, 12 Apr 2018 09:15:23 GMT',
lastSignInTime: 'Thu, 03 May 2018 03:57:06 GMT' },
providerData:
[ UserInfo {
uid: '[email protected]',
displayName: undefined,
email: '[email protected]',
photoURL: undefined,
providerId: 'password',
phoneNumber: undefined } ],
passwordHash: 'U..base64..Q=',
passwordSalt: undefined,
customClaims: undefined,
tokensValidAfterTime: 'Thu, 12 Apr 2018 09:15:23 GMT' }
There appears to be no verification functions as part of the Firebase Admin SDK admin.auth()
.
Should I implement the SCRYPT verification myself by finding an algorithm or ready-made Node module, or should I take the absence of any verification functions as a sign that this is not the best approach?
If so, please recommend a better design, bearing in mind this is a prototype project and to implement full Oauth2 would be quite time consuming.