我在本地 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
passwordHash(字符串或空)
用户的哈希密码(base64 编码),仅当 Firebase Auth 使用散列算法(SCRYPT)。如果使用不同的哈希算法 上传此用户时已使用过,这在迁移时很常见 对于另一个身份验证系统,这将是一个空字符串。如果没有密码 设置后,这将为空。仅当用户处于 从 listUsers() 获得。
密码Salt(字符串或空)
用户的密码盐(base64 编码),仅当 Firebase Auth 时 使用散列算法(SCRYPT)。如果使用不同的哈希算法 已用于上传此用户,典型情况是从另一个用户迁移时 身份验证系统,这将是一个空字符串。如果没有设置密码,则此 将为空。仅当用户从以下位置获取时才可用 列出用户()。
UserRecord 被检索并包含 SCRYPTd
passwordHash
和 passwordSalt
属性。
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' }
Firebase Admin SDK 中似乎没有验证功能
admin.auth()
。
我应该通过寻找算法或现成的 Node 模块来自己实现 SCRYPT 验证,还是应该将缺乏任何验证功能视为这不是最好的方法?
如果是这样,请推荐一个更好的设计,记住这是一个原型项目,实施完整的 Oauth2 将非常耗时。
根据评论中的要求,以下是一些通过 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 = '[email protected]';
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.
// ...
}
});
目前,只有一种可行的方法可以在 Admin SDK 中检查 Firebase 身份验证注册用户的电子邮件/密码。
const credential =
await https.post('https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyCF4WqBVkRdwdL_JEz0P4lZ2fm62iqdeQ4', {
email: data.email,
password: data.password
})
// Credential, if valid, will contain this
// displayName: "John Smith"
// email: "[email protected]"
// idToken: "some-huge-token-id-string"
// kind: "identitytoolkit#VerifyPasswordResponse"
// localId: "some-local-id"
// registered: true
获取此信息后,您可以做任何您想做的事情。 请注意,它仍然会为您生成一个令牌,但是,如果函数调用之外的任何内容都知道该令牌,则由您决定。