Quyền Firebase bị từ chối


123

Tôi là người mới viết mã và đang gặp khó khăn.

Tôi có mã này để gửi dữ liệu tới 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: ""
});

Tuy nhiên, tôi vẫn gặp lỗi:

CẢNH BÁO FIREBASE: đặt tại / users / (GoogleID) không thành công: allow_denied 2016-05-23 22: 52: 42.707 firebase.js: 227 Uncaught (trong lời hứa) Lỗi: PERMISSION_DENIED: Quyền bị từ chối (…)

Khi tôi cố gắng tìm kiếm điều này, nó nói về các quy tắc cho Firebase, có vẻ như bằng ngôn ngữ mà tôi chưa học (hoặc nó chỉ lướt qua đầu tôi). Ai đó có thể giải thích những gì đang gây ra vấn đề? Tôi nghĩ rằng đó là tôi đang yêu cầu nó lưu trữ email và tên hiển thị của người dùng và bạn chỉ không được phép làm điều này, nhưng khi tôi lấy chúng ra, tôi vẫn gặp sự cố tương tự. Có cách nào để tránh lỗi này mà không cần đặt ra các quy tắc, hoặc có những quy tắc nào đó mà tôi có thể tự dạy mình cách viết trong một ngày, hay tôi chỉ là một lối thoát cho giải đấu của tôi?

Cảm ơn vì bất kì sự giúp đỡ!

Câu trả lời:


250

Theo mặc định, cơ sở dữ liệu trong một dự án trong Bảng điều khiển Firebase chỉ có thể đọc / ghi bởi người dùng quản trị (ví dụ: trong Chức năng đám mây hoặc các quy trình sử dụng SDK quản trị). Người dùng SDK phía máy khách thông thường không thể truy cập cơ sở dữ liệu, trừ khi bạn thay đổi quy tắc bảo mật phía máy chủ.


Bạn có thể thay đổi các quy tắc để cơ sở dữ liệu chỉ có thể đọc / ghi bởi người dùng đã xác thực:

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

Xem phần bắt đầu nhanh để biết các quy tắc bảo mật của Cơ sở dữ liệu Firebase .

Nhưng vì bạn không đăng nhập người dùng từ mã của mình, nên cơ sở dữ liệu từ chối bạn truy cập vào dữ liệu. Để giải quyết vấn đề đó, bạn sẽ cần cho phép truy cập chưa được xác thực vào cơ sở dữ liệu của mình hoặc đăng nhập người dùng trước khi truy cập cơ sở dữ liệu.

Cho phép truy cập chưa được xác thực vào cơ sở dữ liệu của bạn

Cách giải quyết đơn giản nhất hiện tại (cho đến khi hướng dẫn được cập nhật) là vào bảng Cơ sở dữ liệu trong bảng điều khiển dành cho bạn dự án, chọn tab Quy tắc và thay thế nội dung bằng các quy tắc sau:

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

Điều này làm cho cơ sở dữ liệu mới của bạn có thể đọc và ghi được bởi bất kỳ ai biết URL của cơ sở dữ liệu. Hãy chắc chắn bảo mật lại cơ sở dữ liệu của bạn trước khi bạn đi vào sản xuất, nếu không ai đó có thể bắt đầu lạm dụng nó.

Đăng nhập người dùng trước khi truy cập cơ sở dữ liệu

Để có (một chút) giải pháp tốn thời gian hơn nhưng an toàn hơn, hãy gọi một trong các signIn...phương pháp Xác thực Firebase để đảm bảo người dùng đã đăng nhập trước khi truy cập cơ sở dữ liệu. Cách đơn giản nhất để làm điều này là sử dụng xác thực ẩn danh :

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

Và sau đó đính kèm người nghe của bạn khi đăng nhập được phát hiện

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
Cảm ơn - đã sử dụng bản sửa lỗi không an toàn và trích dẫn câu trả lời của bạn trong phần trả lời cho một câu hỏi tương tự để xử lý các vấn đề về quyền Firebase trong quá khứ trong hướng dẫn Ember này . Nhưng chúng ta thêm mã xác thực ẩn danh (an toàn) ở đâu?
Dave Everitt

2
OMG đó là một giờ. Tôi đã có cái này trong đó nhưng các giá trị là FALSE ... Tôi chỉ bỏ qua nó. Thay đổi họ TRUE và bam, ứng dụng đang làm việc như bạn nghĩ ...
Andy

OMG, tôi cũng vậy, không thể tìm ra lý do tại sao chúng không được cấp quyền khi cả hai đều đã được đặt thành false (cho đến khi tôi đọc bình luận của bạn). duh, không có sai lầm., cả hai đều phải đúng khi bạn công khai nó (đọc). Cảm ơn bạn đã chỉ ra lỗi của riêng bạn, bạn đã giúp tôi tìm ra nó. Đối với bản ghi, tôi đã thay đổi quy tắc của mình thành sau: ".read": true và sau đó nó bắt đầu hoạt động.
Contractwolf,

@Andy Cảm ơn anh bạn, tôi cũng vậy và thấy bình luận của bạn vừa giải quyết được vấn đề của tôi;)
Mahmudul Hasan Sohag

86

Tôi đã gặp phải vấn đề tương tự và phát hiện ra rằng lỗi này là do các quy tắc được đặt không chính xác cho các hoạt động đọc / ghi cho cơ sở dữ liệu thời gian thực. Theo mặc định, google firebase ngày nay tải cửa hàng đám mây không phải cơ sở dữ liệu thời gian thực. Chúng ta cần chuyển sang thời gian thực và áp dụng các quy tắc chính xác.

nhập mô tả hình ảnh ở đây

Như chúng ta có thể thấy, nó nói rằng đám mây Firestore không phải cơ sở dữ liệu thời gian thực, sau khi chuyển sang cơ sở dữ liệu chính xác, hãy áp dụng các quy tắc dưới đây:

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

3
UI chết tiệt! Tôi đã dành cả ngày, để tìm ra lý do tại sao tôi có các quy tắc khác nhau ... Ah ... Đó là cho "cửa hàng lửa đám mây" ... Cảm ơn!
Alexey Volodko

43

Đi tới tùy chọn "Cơ sở dữ liệu" mà bạn đã đề cập.

  1. Ở đó trên Blue Header, bạn sẽ tìm thấy một menu thả xuống có nội dung Cloud Firestore Beta
  2. Thay đổi nó thành "Cơ sở dữ liệu thời gian thực"
  3. Đi tới Quy tắc và đặt .write .read cả hai thành true

Đã sao chép từ đây .


11

Vào cơ sở dữ liệu, bên cạnh tiêu đề có 2 tùy chọn:

Cloud Firestore, Cơ sở dữ liệu thời gian thực

Chọn Cơ sở dữ liệu thời gian thực và đi tới quy tắc

thay đổi quy tắc thành true.

Điều này đã giải quyết vấn đề của tôi.


4
  1. Mở firebase, chọn cơ sở dữ liệu ở phía bên trái.
  2. Bây giờ ở bên phải, chọn [Cơ sở dữ liệu thời gian thực] từ menu thả xuống và thay đổi các quy tắc thành: {"rules": {".read": true, ".write": true}}

nó hoạt động .. !!


5
Điều này đã được nói trong câu trả lời khác. Ngoài ra, khi bạn đề xuất điều này, hãy đảm bảo thêm cảnh báo vì điều này không lưu!
André Kool

4

Được, nhưng bạn không muốn mở toàn bộ cơ sở dữ liệu thời gian thực! Bạn cần một cái gì đó như thế này.

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

hoặc là

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

2

Một giải pháp khác là thực sự tạo hoặc đăng nhập người dùng tự động nếu bạn đã có sẵn thông tin đăng nhập. Đây là cách tôi thực hiện bằng cách sử dụng 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);
        });
}

Đây thực sự là một bảo mật khôn ngoan.
ASH
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.