Odmowa dostępu do Firebase

125

Jestem stosunkowo nowy w programowaniu i mam problemy.

Mam ten kod do wysyłania danych do firebase

app.userid = app.user.uid

var userRef = app.dataInfo.child(app.users);

var useridRef = userRef.child(app.userid);

useridRef.set({
  locations: "",
  theme: "",
  colorScheme: "",
  food: ""
});

Jednak ciągle otrzymuję błąd:

OSTRZEŻENIE FIREBASE: ustawiono na / users / (GoogleID) nie powiodło się: Permissions_denied 2016-05-23 22: 52: 42.707 firebase.js: 227 Uncaught (w obietnicy) Error: PERMISSION_DENIED: Permission denied (…)

Kiedy próbuję to sprawdzić, mówi o regułach dla Firebase, który wydaje się być w języku, którego jeszcze się nie nauczyłem (lub po prostu przechodzi mi przez głowę). Czy ktoś może wyjaśnić, co jest przyczyną problemu? Myślałem, że to dlatego, że prosiłem o przechowywanie adresu e-mail i nazwy wyświetlanej użytkownika, a tobie nie wolno było tego robić, ale kiedy je wyciągnąłem, nadal miałem ten sam problem. Czy istnieje sposób na uniknięcie tego błędu bez ustalania reguł, czy może zasady są czymś, czego mogę się nauczyć pisać w ciągu jednego dnia, czy po prostu wypadłem z ligi?

Dzięki za pomoc!

Robert Prine
źródło

Odpowiedzi:

252

Domyślnie baza danych w projekcie w Konsoli Firebase jest odczytywana / zapisywana tylko przez użytkowników administracyjnych (np. W Cloud Functions lub w procesach korzystających z pakietu Admin SDK). Użytkownicy zwykłych zestawów SDK po stronie klienta nie mogą uzyskać dostępu do bazy danych, chyba że zmienisz reguły zabezpieczeń po stronie serwera.


Możesz zmienić reguły, aby baza danych była odczytywalna / zapisywalna tylko dla uwierzytelnionych użytkowników:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

Zobacz krótkie wprowadzenie do reguł bezpieczeństwa Bazy danych Firebase .

Ale ponieważ nie rejestrujesz użytkownika za pomocą kodu, baza danych odmawia Ci dostępu do danych. Aby rozwiązać ten problem, musisz zezwolić na nieuwierzytelniony dostęp do bazy danych lub zalogować użytkownika przed uzyskaniem dostępu do bazy danych.

Zezwól na nieuwierzytelniony dostęp do bazy danych

Najprostszym rozwiązaniem w tej chwili (do czasu aktualizacji samouczka) jest przejście do panelu Bazy danych w konsoli projektu, wybranie zakładki Reguły i zastąpienie treści następującymi regułami:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

To sprawia, że ​​twoja nowa baza danych jest czytelna i zapisywalna dla każdego, kto zna adres URL bazy danych. Pamiętaj, aby ponownie zabezpieczyć swoją bazę danych przed rozpoczęciem produkcji, w przeciwnym razie ktoś prawdopodobnie zacznie jej nadużywać.

Zarejestruj użytkownika przed uzyskaniem dostępu do bazy danych

Aby uzyskać (nieco) bardziej czasochłonne, ale bezpieczniejsze rozwiązanie, wywołaj jedną z signIn...metod uwierzytelniania Firebase, aby upewnić się, że użytkownik jest zalogowany przed uzyskaniem dostępu do bazy danych. Najprostszym sposobem na to jest użycie uwierzytelniania anonimowego :

firebase.auth().signInAnonymously().catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // ...
});

A następnie dołącz słuchaczy, gdy zostanie wykryte logowanie

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
    var userRef = app.dataInfo.child(app.users);

    var useridRef = userRef.child(app.userid);

    useridRef.set({
      locations: "",
      theme: "",
      colorScheme: "",
      food: ""
    });

  } else {
    // User is signed out.
    // ...
  }
  // ...
});
Frank van Puffelen
źródło
1
Dzięki - skorzystałem z niezabezpieczonej poprawki i zacytowałem swoją odpowiedź w odpowiedzi na podobne pytanie, aby przejść przez problemy z uprawnieniami Firebase w tym samouczku Ember . Ale gdzie dodamy (bezpieczny) anonimowy kod autoryzacji?
Dave Everitt
2
OMG tam idzie godzinę. Miałem to tam, ale wartości były FALSE ... Po prostu to przeoczyłem. Zmieniono je na TRUE i bam, aplikacja działa tak, jak myślisz ...
Andy
OMG, ja też, nie mogłem dowiedzieć się, dlaczego nie udało im się uzyskać uprawnień, skoro oba były już ustawione na fałsz (dopóki nie przeczytam twojego komentarza). duh, noob błąd., oba powinny być prawdziwe, kiedy udostępniasz je publicznie (czyta). Dziękuję za wskazanie własnego błędu, pomogłeś mi go rozgryźć. Dla przypomnienia, zmieniłem regułę na „.read”: true i wtedy zaczęło działać.
contractorwolf
@Andy Dzięki stary, to samo dla mnie i widząc twój komentarz, właśnie rozwiązałem mój problem;)
Mahmudul Hasan Sohag
86

Miałem podobny problem i odkryłem, że ten błąd był spowodowany nieprawidłowymi regułami ustawionymi dla operacji odczytu / zapisu dla bazy danych czasu rzeczywistego. Domyślnie Google Firebase obecnie ładuje sklep w chmurze, a nie bazę danych w czasie rzeczywistym. Musimy przejść do czasu rzeczywistego i zastosować odpowiednie zasady.

wprowadź opis obrazu tutaj

Jak widać, jest to napisane w chmurze Firestore, a nie w czasie rzeczywistym, po przełączeniu na poprawną bazę danych zastosuj poniższe zasady:

{
   "rules": {
       ".read": true,
       ".write": true
     }
 }
po prostu bądź dziwny
źródło
3
Cholerny interfejs! Spędziłem cały dzień, zastanawiając się, dlaczego mam inne zasady ... Ach ... To było dla "Cloud Firestore" ... Dzięki!
Alexey Volodko
43

Przejdź do wspomnianej opcji „Baza danych”.

  1. Tam w niebieskim nagłówku znajdziesz menu z napisem Cloud Firestore Beta
  2. Zmień to na „Baza danych czasu rzeczywistego”
  3. Przejdź do Reguł i ustaw .write .read oba na true

Skopiowano stąd .

Ahmed Adewale
źródło
11

Przejdź do bazy danych, obok tytułu znajdują się 2 opcje:

Cloud Firestore, baza danych czasu rzeczywistego

Wybierz Baza danych czasu rzeczywistego i przejdź do reguł

Zmień reguły na prawdziwe.

Jaywant Narwade
źródło
4

OK, ale nie chcesz otwierać całej bazy danych czasu rzeczywistego! Potrzebujesz czegoś takiego.

{
  /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
  "rules": {
    ".read": "auth.uid !=null",
    ".write": "auth.uid !=null"
  }
}

lub

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid"
      }
    }
  }
}
Ondřej Bauer
źródło
4
  1. Otwórz firebase, wybierz bazę danych po lewej stronie.
  2. Teraz po prawej stronie wybierz [Baza danych czasu rzeczywistego] od utopionego i zmień reguły na:
{
  "rules": {
    ".read": true,
    ".write": true
  }
}
Anindya Sankar Dasgupta
źródło
7
Zostało to już powiedziane w drugiej odpowiedzi. Również jeśli to zasugerujesz, dodaj ostrzeżenie, ponieważ to nie jest zapisywanie!
André Kool,
1

Innym rozwiązaniem jest automatyczne utworzenie lub zalogowanie użytkownika, jeśli masz już pod ręką poświadczenia. Oto jak to robię za pomocą zwykłego JS.

function loginToFirebase(callback)
{
    let email = '[email protected]';
    let password = 'xxxxxxxxxxxxxx';
    let config =
    {
        apiKey: "xxx",
        authDomain: "xxxxx.firebaseapp.com",
        projectId: "xxx-xxx",
        databaseURL: "https://xxx-xxx.firebaseio.com",
        storageBucket: "gs://xx-xx.appspot.com",
    };

    if (!firebase.apps.length)
    {
        firebase.initializeApp(config);
    }

    let database = firebase.database();
    let storage = firebase.storage();

    loginFirebaseUser(email, password, callback);
}

function loginFirebaseUser(email, password, callback)
{
    console.log('Logging in Firebase User');

    firebase.auth().signInWithEmailAndPassword(email, password)
        .then(function ()
        {
            if (callback)
            {
                callback();
            }
        })
        .catch(function(login_error)
        {
            let loginErrorCode = login_error.code;
            let loginErrorMessage = login_error.message;

            console.log(loginErrorCode);
            console.log(loginErrorMessage);

            if (loginErrorCode === 'auth/user-not-found')
            {
                createFirebaseUser(email, password, callback)
            }
        });
}

function createFirebaseUser(email, password, callback)
{
    console.log('Creating Firebase User');

    firebase.auth().createUserWithEmailAndPassword(email, password)
        .then(function ()
        {
            if (callback)
            {
                callback();
            }
        })
        .catch(function(create_error)
        {
            let createErrorCode = create_error.code;
            let createErrorMessage = create_error.message;

            console.log(createErrorCode);
            console.log(createErrorMessage);
        });
}
Parampal Pooni
źródło
1
To jest naprawdę złe z punktu widzenia bezpieczeństwa.
ASH