首页 > 解决方案 > 如何使用 Firebase Admin SDK(服务器端)验证电子邮件/密码凭据?

问题描述

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

调用myclitool login,一次性提示询问用户他们的电子邮件和密码。CLI 工具使用 HTTP POST 请求通过 SSL 将请求正文中的电子邮件和密码发送到 Express 服务器。

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

CLI 工具的每个后续调用都将在 Firestore 帐户集合中查找私有 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 文档说: https ://firebase.google.com/docs/reference/admin/node/admin.auth.UserRecord

密码哈希(字符串或空)

用户的哈希密码(base64 编码),仅在使用 Firebase Auth 哈希算法 (SCRYPT) 时。如果在上传此用户时使用了不同的哈希算法,这在从另一个 Auth 系统迁移时很典型,这将是一个空字符串。如果没有设置密码,这将为空。这仅在从 listUsers() 获取用户时可用。

密码盐(字符串或空)

用户的密码 salt(base64 编码),仅当使用 Firebase Auth 哈希算法 (SCRYPT) 时。如果使用不同的散列算法上传此用户,通常在从另一个 Auth 系统迁移时,这将是一个空字符串。如果没有设置密码,这将为空。这仅在从 listUsers() 获取用户时可用。

检索 UserRecord 并包含 SCRYPTdpasswordHashpasswordSalt属性。

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()

我应该通过查找算法或现成的 Node 模块自己实现 SCRYPT 验证,还是应该将没有任何验证功能作为这不是最佳方法的标志?

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

标签: firebasefirebase-authenticationgoogle-cloud-firestoregoogle-cloud-functionsfirebase-admin

解决方案


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

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

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.
    // ...
  }
});

推荐阅读