#javascript #firebase #google-cloud-firestore #firebase-security
#javascript #firebase #google-облако-firestore #firebase-безопасность
Вопрос:
Я реализовал регистрацию в Firebase с именем пользователя, электронной почтой и паролем. В основном то, что я делаю, это:
1- Создайте пользователя с электронной почтой и паролем (если имя пользователя и электронная почта не используются другими пользователями)
2- Добавьте имя пользователя для пользователя
Вот так:
firebase
.createUserWithEmailAndPassword(email, password)
.then((currentUser) => {
// Get the username from the input
const username = this.usernameInput.current.getText();
// Create a user with this username and the current user uid in the db
firebase.createUserWithUsername(username, currentUser.user.uid); // <----------
})
.catch((err) => {
// ...
});
И моя функция createUserWithUsername в основном делает это:
createUserWithUsername = (username, userId) => {
/*
Create a document in the usernames collection
which uid (of the document itself, not a field) is the given username.
*/
// Pass username to lowercase
username = username.toLowerCase();
// Initial user's data
const data = {
email: this.auth.currentUser.email,
username,
};
return this.db
.collection("usernames")
.doc(username)
.set({ userId })
.then(() => {
this.db.collection("users").doc(userId).set(data);
})
.catch((err) => {
console.log(err);
throw err;
});
/*
Pd: As firestore automatically removes empty documents, we have to
assign them a field. The user's id is a good option, because it will help us to
update usernames faster, acting like a 'Foreign Key' in a NoSql DB.
*/
};
Мой вопрос? Неправильно ли оставлять этот код на стороне клиента? Может ли это быть проблемой безопасности? Нужно ли мне перенести это в облачную функцию / серверную часть?
Это мое правило безопасности firestore для коллекции имен пользователей:
match /usernames/{username} {
function isUsernameAvailable() {
return !exists(/databases/$(database)/documents/usernames/$(username));
}
allow read: if true;
allow write, update: if isSignedIn() amp;amp; isUsernameAvailable();
// TODO - Allow delete?
}
Я был бы очень признателен за любое руководство по этому вопросу. Спасибо.
Комментарии:
1. Я думаю, вы захотите сделать это в пакетной записи или транзакции, чтобы обе записи были успешными / неудачными в тандеме. Затем вы можете использовать
existsAfter()
вместоexists()
для проверки данных, как это будет, если запись разрешена.2. @FrankvanPuffelen спасибо за отзыв! Почему я должен использовать транзакции для этого (я никогда их не использовал)? В моем коде я создаю документ в своей коллекции имен пользователей с идентификатором пользователя… Разве документы Firestore не создаются атомарно?!
3. Если новый статус документа зависит от существующего значения в этом документе, именно тогда вам нужна транзакция. Если это не так, вы бы использовали пакетную запись.
4. АААА!!! Да, спасибо тебе, чувак! Теперь, если имя пользователя не может быть записано или идентификатор пользователя, вся операция завершается неудачей!