如何使用Firebase Admin SDK(服务器端)验证电子邮件/密码凭据?

如何使用Firebase Admin SDK(服务器端)验证电子邮件/密码凭据?,firebase,firebase-authentication,google-cloud-firestore,google-cloud-functions,firebase-admin,Firebase,Firebase Authentication,Google Cloud Firestore,Google Cloud Functions,Firebase Admin,我已经编写了一个Google Cloud Function Express应用程序和一个在本地Mac上使用Node.js的命令行工具 调用myclitool login,会出现一个一次性提示,要求用户输入他们的电子邮件和密码。CLI工具使用HTTP POST请求通过SSL将请求正文中的电子邮件和密码发送到Express server 服务器将发回一个私有API密钥(由用户注册时的触发器函数生成),该密钥将写入~/.myclitoolrc,并将用于对我的API端点的所有后续调用 来自CLI工具的每

我已经编写了一个Google Cloud Function Express应用程序和一个在本地Mac上使用Node.js的命令行工具

调用
myclitool login
,会出现一个一次性提示,要求用户输入他们的电子邮件和密码。CLI工具使用HTTP POST请求通过SSL将请求正文中的电子邮件和密码发送到Express server

服务器将发回一个私有API密钥(由用户注册时的触发器函数生成),该密钥将写入
~/.myclitoolrc
,并将用于对我的API端点的所有后续调用

来自CLI工具的每个后续调用都将在Firestore accounts集合中查找私有API密钥,并基于每个API调用进行身份验证

admin.firestore()
  .collection('accounts')
  .where('privateApiKey', '==', privateApiKey)
  .get() // and so on
到目前为止,以下代码将找到
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);
    });
  });
};
Firebase文档说明:

密码哈希(字符串或null)

用户的哈希密码(base64编码),仅当Firebase验证 使用哈希算法(SCRYPT)。如果使用不同的哈希算法 已在上载此用户时使用,这是迁移时的典型情况 从另一个身份验证系统,这将是一个空字符串。如果没有密码 如果已设置,则该值将为空。这仅在用户处于活动状态时可用 从listUsers()获取

密码salt(字符串或null)

用户密码salt(base64编码),仅当Firebase验证 使用哈希算法(SCRYPT)。如果使用不同的哈希算法 已用于上载此用户,通常在从其他用户迁移时使用 验证系统,这将是一个空字符串。如果未设置密码,则此 将为空。这仅在从以下位置获取用户时可用 listUsers()

将检索UserRecord并包含SCRYPTd
passwordHash
passwordSalt
属性

UserRecord {
  uid: 'kjep.[snip]..i2',
  email: 'email@example.com',
  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@example.com',
       displayName: undefined,
       email: 'email@example.com',
       photoURL: undefined,
       providerId: 'password',
       phoneNumber: undefined } ],
  passwordHash: 'U..base64..Q=',
  passwordSalt: undefined,
  customClaims: undefined,
  tokensValidAfterTime: 'Thu, 12 Apr 2018 09:15:23 GMT' }
Firebase Admin SDK中似乎没有验证功能
Admin.auth()

我应该通过查找算法或现成的节点模块来实现SCRYPT验证,还是应该将缺少任何验证函数视为这不是最佳方法的迹象


如果是这样,请推荐更好的设计,记住这是一个原型项目,实现完整的Oauth2将非常耗时。

根据评论中的要求,下面是一些示例代码,用于通过Firebase Javascript SDK使用Node.js访问云Firestore(强制执行安全规则)

v4.13.0中存在一个bug(现已关闭)。我还没有测试4.13.1,但是修复程序已经合并到
master
分支中。如果它不起作用,您应该尝试v4.12.0


如果您只想允许从节点应用程序对云Firestore进行受控访问,则可以使用标准Firebase Javascript SDK并强制执行安全规则。如果这是您的用例,请告诉我,我将发布一些代码示例。我希望通过RESTful端点公开我的服务,因此使用Firebase JavaScript SDK可能不适合CLI工具提供的所有命令类型。如果能看到更多的例子来获得更多的想法,我将不胜感激。
const firebase = require('firebase');
require("firebase/firestore");

// Initialize Firebase
// You get these details from the Firebase Console
let config = {
  apiKey: "yourAPIkey",
  authDomain: "yourAuthDomain",
  databaseURL: "https://yourProjectID.firebaseio.com",
  projectId: "yourProjectID",
  messagingSenderId: "yourId"
};
firebase.initializeApp(config);

let email = 'yourUser@example.com';
let password = 'yourVerySecurePassword';

firebase.auth().signInWithEmailAndPassword(email, password)
  .catch(error => {
    console.log(error);
  });

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    console.log('I am logged in');

    // Initialise Firestore
    const firestore = firebase.firestore();
    const settings = {timestampsInSnapshots: true};
    firestore.settings(settings);

    return firestore
      .collection('accounts')
      .where('privateApiKey', '==', privateApiKey)
      .get()
      .then((querySnapshot) => {
        querySnapshot.forEach((documentSnapshot) => {
          if (documentSnapshot.exists) {
            console.log(documentSnapshot.id);
          }
        });
      });
  } else {
    // User is signed out.
    // ...
  }
});