การอนุญาต Firebase ถูกปฏิเสธ


124

ฉันค่อนข้างใหม่กับการเขียนโค้ดและกำลังมีปัญหา

ฉันมีรหัสนี้เพื่อส่งข้อมูลไปยัง 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: ""
});

อย่างไรก็ตามฉันยังคงได้รับข้อผิดพลาด:

คำเตือน FIREBASE: ตั้งค่าที่ / users / (GoogleID) ล้มเหลว: permission_denied 2016-05-23 22: 52: 42.707 firebase.js: 227 Uncaught (ตามสัญญา) ข้อผิดพลาด: PERMISSION_DENIED: การอนุญาตถูกปฏิเสธ (…)

เมื่อฉันพยายามค้นหาสิ่งนี้มันจะพูดถึงกฎสำหรับ Firebase ซึ่งดูเหมือนว่าจะเป็นภาษาที่ฉันยังไม่ได้เรียนรู้ (หรือมันเป็นแค่การพูดเหนือหัวของฉัน) ใครช่วยอธิบายได้ไหมว่าอะไรเป็นสาเหตุของปัญหา ฉันคิดว่าฉันกำลังขอให้มันจัดเก็บอีเมลและชื่อที่แสดงของผู้ใช้และคุณไม่ได้รับอนุญาตให้ทำสิ่งนี้ แต่เมื่อฉันนำสิ่งเหล่านั้นออกไปฉันก็ยังคงมีปัญหาเหมือนเดิม มีวิธีหลีกเลี่ยงข้อผิดพลาดนี้โดยไม่ต้องตั้งกฎหรือเป็นกฎบางอย่างที่ฉันสามารถสอนตัวเองได้ว่าจะเขียนอย่างไรในหนึ่งวันหรือฉันแค่ออกจากลีก

ขอบคุณสำหรับความช่วยเหลือ!

คำตอบ:


250

โดยค่าเริ่มต้นฐานข้อมูลในโปรเจ็กต์ในFirebase Consoleจะอ่าน / เขียนได้โดยผู้ใช้ระดับผู้ดูแลระบบเท่านั้น (เช่นใน Cloud Functions หรือกระบวนการที่ใช้ Admin SDK) ผู้ใช้ SDK ฝั่งไคลเอ็นต์ทั่วไปไม่สามารถเข้าถึงฐานข้อมูลได้เว้นแต่คุณจะเปลี่ยนกฎความปลอดภัยฝั่งเซิร์ฟเวอร์


คุณสามารถเปลี่ยนกฎเพื่อให้ฐานข้อมูลสามารถอ่าน / เขียนได้โดยผู้ใช้ที่พิสูจน์ตัวตนเท่านั้น:

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

ดูQuickStart สำหรับ Firebase กฎความปลอดภัยฐานข้อมูล

แต่เนื่องจากคุณไม่ได้ลงชื่อผู้ใช้จากรหัสของคุณฐานข้อมูลจึงปฏิเสธว่าคุณเข้าถึงข้อมูล ในการแก้ปัญหานั้นคุณจะต้องอนุญาตการเข้าถึงฐานข้อมูลของคุณโดยไม่ได้รับการรับรองหรือลงชื่อเข้าใช้ผู้ใช้ก่อนเข้าถึงฐานข้อมูล

อนุญาตให้เข้าถึงฐานข้อมูลของคุณโดยไม่ได้รับการพิสูจน์ตัวตน

วิธีแก้ปัญหาที่ง่ายที่สุดในขณะนี้ (จนกว่าบทช่วยสอนจะได้รับการอัปเดต) คือเข้าไปที่แผงฐานข้อมูลในคอนโซลสำหรับโครงการของคุณเลือกแท็บกฎและแทนที่เนื้อหาด้วยกฎเหล่านี้:

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

สิ่งนี้ทำให้ฐานข้อมูลใหม่ของคุณสามารถอ่านและเขียนได้โดยทุกคนที่รู้ URL ของฐานข้อมูล ตรวจสอบให้แน่ใจว่าได้รักษาความปลอดภัยฐานข้อมูลของคุณอีกครั้งก่อนที่คุณจะเริ่มการผลิตมิฉะนั้นอาจมีคนเริ่มใช้งานในทางที่ผิด

ลงชื่อเข้าใช้ผู้ใช้ก่อนเข้าถึงฐานข้อมูล

สำหรับวิธีแก้ปัญหาที่ใช้เวลานานกว่า แต่ปลอดภัยกว่า (เล็กน้อย) ให้เรียกใช้หนึ่งในsignIn...วิธีการตรวจสอบสิทธิ์ Firebaseเพื่อให้แน่ใจว่าผู้ใช้ลงชื่อเข้าใช้ก่อนเข้าถึงฐานข้อมูล วิธีที่ง่ายที่สุดคือใช้การพิสูจน์ตัวตนแบบไม่ระบุชื่อ :

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

จากนั้นแนบผู้ฟังของคุณเมื่อตรวจพบการลงชื่อเข้าใช้

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

1
ขอขอบคุณ - ใช้การแก้ไขที่ไม่ปลอดภัยและอ้างคำตอบของคุณในการตอบกลับคำถามที่คล้ายกันเพื่อความคืบหน้าปัญหาการอนุญาต Firebase ที่ผ่านมาในบทแนะนำ Emberนี้ แต่เราจะเพิ่มรหัสรับรองความถูกต้อง (ปลอดภัย) ที่ไม่ระบุตัวตนได้ที่ไหน?
Dave Everitt

2
OMG ไปหนึ่งชั่วโมง ฉันมีสิ่งนี้อยู่ในนั้น แต่ค่าเป็นเท็จ ... ฉันมองข้ามมันไป เปลี่ยนเป็น TRUE แล้วแบมใช้งานได้อย่างที่คิด ...
Andy

OMG ฉันก็เช่นกันฉันไม่สามารถเข้าใจได้ว่าทำไมพวกเขาถึงล้มเหลวในการอนุญาตเมื่อทั้งคู่ตั้งค่าเป็นเท็จ (จนกว่าฉันจะอ่านความคิดเห็นของคุณ) duh, noob ผิดพลาดทั้งคู่ควรจะเป็นจริงเมื่อคุณเปิดให้คนทั่วไปเข้าชม (อ่าน) ขอขอบคุณที่ชี้ให้เห็นข้อผิดพลาดของคุณเองคุณช่วยฉันคิดออก สำหรับบันทึกนี้ฉันเปลี่ยนกฎของฉันเป็น: ".read": true จากนั้นก็เริ่มทำงาน
contractwolf

@Andy ขอบคุณผู้ชายเช่นเดียวกับฉันและเห็นความคิดเห็นของคุณเพิ่งแก้ไขปัญหาของฉัน;)
Mahmudul Hasan Sohag

86

ฉันประสบปัญหาที่คล้ายกันและพบว่าข้อผิดพลาดนี้เกิดจากกฎที่ตั้งไว้ไม่ถูกต้องสำหรับการดำเนินการอ่าน / เขียนสำหรับฐานข้อมูลแบบเรียลไทม์ ตามค่าเริ่มต้น google firebase ในปัจจุบันโหลด cloud store ไม่ใช่ฐานข้อมูลแบบเรียลไทม์ เราจำเป็นต้องเปลี่ยนไปใช้เวลาจริงและใช้กฎที่ถูกต้อง

ใส่คำอธิบายภาพที่นี่

ดังที่เราเห็นว่า Cloud Firestore ไม่ใช่ฐานข้อมูลแบบเรียลไทม์เมื่อเปลี่ยนไปใช้ฐานข้อมูลที่ถูกต้องแล้วให้ใช้กฎด้านล่าง:

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

3
UI เหี้ย! ฉันใช้เวลาทั้งวันเพื่อหาคำตอบว่าทำไมฉันถึงมีกฎที่แตกต่างกัน ... อ้า ... สำหรับ "cloud firestore" ... ขอบคุณ!
Alexey Volodko

43

ไปที่ตัวเลือก "ฐานข้อมูล" ที่คุณกล่าวถึง

  1. ที่ส่วนหัวสีน้ำเงินคุณจะพบเมนูแบบเลื่อนลงซึ่งมีข้อความว่า Cloud Firestore Beta
  2. เปลี่ยนเป็น "ฐานข้อมูลเรียลไทม์"
  3. ไปที่กฎและตั้งค่า. เขียน. อ่านทั้งคู่เป็น true

คัดลอกมาจากที่นี่


11

ไปที่ฐานข้อมูลถัดจากชื่อมี 2 ตัวเลือก:

Cloud Firestore ฐานข้อมูลเรียลไทม์

เลือกฐานข้อมูลเรียลไทม์และไปที่กฎ

เปลี่ยนกฎเป็นจริง

สิ่งนี้ช่วยแก้ปัญหาของฉันได้


4
  1. เปิด firebase เลือกฐานข้อมูลทางด้านซ้ายมือ
  2. ทางด้านขวามือให้เลือก [ฐานข้อมูลเรียลไทม์] จากเมนูแบบเลื่อนลงและเปลี่ยนกฎเป็น: {"กฎ": {".read": true, ".write": true}}

มันได้ผล..!!


5
สิ่งนี้ได้กล่าวไปแล้วในคำตอบอื่น ๆ นอกจากนี้เมื่อคุณแนะนำสิ่งนี้อย่าลืมเพิ่มคำเตือนเพราะไม่ได้บันทึก!
André Kool

4

ตกลง แต่คุณไม่ต้องการเปิดฐานข้อมูลเรียลไทม์ทั้งหมด! คุณต้องการสิ่งนี้

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

หรือ

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid"
      }
    }
  }
}

1

อีกวิธีหนึ่งคือการสร้างหรือเข้าสู่ระบบผู้ใช้โดยอัตโนมัติหากคุณมีข้อมูลประจำตัวอยู่แล้ว นี่คือวิธีการใช้ Plain JS

function loginToFirebase(callback)
{
    let email = 'xx@xx.com';
    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);
        });
}

นี่เป็นการรักษาความปลอดภัยที่ไม่ดีจริงๆ
ASH
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.