如何为匿名用户设置 Firebase 规则,使其只能读写自己的数据
How to set Firebase rules for anonymous users to only read and write their own data
我希望匿名用户只能读写他们自己的数据。我的安全规则如下,但在模拟器和应用程序中出现无法读取错误。
我不确定我的处理方式是否正确。我的主要 objective 是将同一用户的新评估嵌套在他们的 uid 下,这样他们就只能读取、写入和更新他们自己的评估。
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid";
".read": "$uid === auth.uid";
}
}
}
}
这是我的分支目前的样子
这就是我认为完成我需要的东西应该是什么样子的。
Ideal Database structure
auth.gaurd.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from "../../shared/service/auth.service";
import { Observable } from 'rxjs';
import * as firebase from 'firebase';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
uid: string;
constructor(
public authService: AuthService,
public router: Router
){ }
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
this.authStateListener();
return true;
}
authStateListener() {
// [START auth_state_listener]
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
this.uid = user.uid;
console.log("user"+user.isAnonymous)
console.log("uid"+this.uid)
} else {
// User is signed out
return firebase.auth().signOut().then(() => {
localStorage.removeItem('user');
this.router.navigate(['sign-in']);
})
}
});
}
}
auth.service.ts
import { Injectable, NgZone, ViewChild, ElementRef, Component } from '@angular/core';
import { User } from "../service/user";
import { auth } from 'firebase/app';
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { ActivatedRoute, Router } from "@angular/router";
import * as firebase from 'firebase';
import "firebase/auth";
@Injectable({
providedIn: 'root'
})
export class AuthService {
userData: any; // Save logged in user data
@ViewChild('btnLogin') btnLogin: HTMLButtonElement;
constructor(
public afs: AngularFirestore, // Inject Firestore service
public afAuth: AngularFireAuth, // Inject Firebase auth service
public router: Router,
private actRoute: ActivatedRoute,
public ngZone: NgZone // NgZone service to remove outside scope warning
) {
}
anonymousSignIn(){
firebase.auth().signInAnonymously()
.then(()=>{
this.router.navigate(['assessment']);
console.log("clicking")
}).catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log("error here")
});
}
**这是在 Firebase 中推送、读取、更新和删除分支的代码。 ReadAssessment 列表应显示匿名用户拥有的所有数据,以便他们阅读。 ** 火-assessment.service.ts
import { AuthGuard } from './../shared/guard/auth.guard';
import { Injectable } from '@angular/core';
import {AngularFireDatabase, AngularFireList, AngularFireObject} from '@angular/fire/database';
import * as firebase from 'firebase';
import {Business} from '../models/business';
import { ActivatedRoute, Router } from '@angular/router';
import { map } from 'rxjs/internal/operators/map';
import { isNgTemplate } from '@angular/compiler';
@Injectable({
providedIn: 'root'
})
export class FireAssessmentService {
assessmentsRef: AngularFireList<any>; // Reference to Assessment data list, its an Observable
assessmentRef: AngularFireObject<any>; // Reference to assessment object
public database = firebase.database();
public UserAssessmentInput;
public ref;
public actRoute: ActivatedRoute;
public router: Router;
public auth: AuthGuard;
constructor(private db: AngularFireDatabase) {
}
CreateAssessment(business: Business ){
const key = this.database.ref('/users').push().key;
this.database.ref('/users').child(key).set(
///this.assessmentsRef.ref('/users').push(
{
busiName: business.busiName
});
}
ReadAssessment(id: string){
this.assessmentRef = this.db.object('users/' + id);
return this.assessmentRef;
}
ReadAssessmentsList(){
this.assessmentsRef = this.db.list('users/');
return this.assessmentsRef;
}
UpdateAssessments (business: Business){
this.assessmentRef.update({
busiName: business.busiName
});
}
DeleteAssessment(){
this.assessmentRef = this.db.object('users/');
this.assessmentRef.remove();
}
business.ts
export interface Business {
$key: string;
busiName: string;
}
现在您正在使用此创建数据:
const key = this.database.ref('/users').push().key;
this.database.ref('/users').child(key).set({
busiName: business.busiName
});
当您调用 push()
时,Firebase 会生成一个新的唯一位置,这是您 JSON 中以 -M...
开头的键。
该值不是当前用户的 UID,因此这些规则不允许用户读取或写入它:
"users": {
"$uid": {
".write": "$uid === auth.uid";
".read": "$uid === auth.uid";
}
}
相反,您应该使用用户的 UID 作为键将数据写入节点下。那看起来像:
const key = this.database.ref('/users').push().key;
if (firebase.auth().currentUser) {
const key = firebase.auth().currentUser.uid;
this.database.ref('/users').child(key).set({
busiName: business.busiName
});
}
else {
console.error("No current user while trying to write business name");
}
我希望匿名用户只能读写他们自己的数据。我的安全规则如下,但在模拟器和应用程序中出现无法读取错误。
我不确定我的处理方式是否正确。我的主要 objective 是将同一用户的新评估嵌套在他们的 uid 下,这样他们就只能读取、写入和更新他们自己的评估。
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid";
".read": "$uid === auth.uid";
}
}
}
}
这是我的分支目前的样子
这就是我认为完成我需要的东西应该是什么样子的。 Ideal Database structure
auth.gaurd.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from "../../shared/service/auth.service";
import { Observable } from 'rxjs';
import * as firebase from 'firebase';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
uid: string;
constructor(
public authService: AuthService,
public router: Router
){ }
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
this.authStateListener();
return true;
}
authStateListener() {
// [START auth_state_listener]
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
this.uid = user.uid;
console.log("user"+user.isAnonymous)
console.log("uid"+this.uid)
} else {
// User is signed out
return firebase.auth().signOut().then(() => {
localStorage.removeItem('user');
this.router.navigate(['sign-in']);
})
}
});
}
}
auth.service.ts
import { Injectable, NgZone, ViewChild, ElementRef, Component } from '@angular/core';
import { User } from "../service/user";
import { auth } from 'firebase/app';
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { ActivatedRoute, Router } from "@angular/router";
import * as firebase from 'firebase';
import "firebase/auth";
@Injectable({
providedIn: 'root'
})
export class AuthService {
userData: any; // Save logged in user data
@ViewChild('btnLogin') btnLogin: HTMLButtonElement;
constructor(
public afs: AngularFirestore, // Inject Firestore service
public afAuth: AngularFireAuth, // Inject Firebase auth service
public router: Router,
private actRoute: ActivatedRoute,
public ngZone: NgZone // NgZone service to remove outside scope warning
) {
}
anonymousSignIn(){
firebase.auth().signInAnonymously()
.then(()=>{
this.router.navigate(['assessment']);
console.log("clicking")
}).catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log("error here")
});
}
**这是在 Firebase 中推送、读取、更新和删除分支的代码。 ReadAssessment 列表应显示匿名用户拥有的所有数据,以便他们阅读。 ** 火-assessment.service.ts
import { AuthGuard } from './../shared/guard/auth.guard';
import { Injectable } from '@angular/core';
import {AngularFireDatabase, AngularFireList, AngularFireObject} from '@angular/fire/database';
import * as firebase from 'firebase';
import {Business} from '../models/business';
import { ActivatedRoute, Router } from '@angular/router';
import { map } from 'rxjs/internal/operators/map';
import { isNgTemplate } from '@angular/compiler';
@Injectable({
providedIn: 'root'
})
export class FireAssessmentService {
assessmentsRef: AngularFireList<any>; // Reference to Assessment data list, its an Observable
assessmentRef: AngularFireObject<any>; // Reference to assessment object
public database = firebase.database();
public UserAssessmentInput;
public ref;
public actRoute: ActivatedRoute;
public router: Router;
public auth: AuthGuard;
constructor(private db: AngularFireDatabase) {
}
CreateAssessment(business: Business ){
const key = this.database.ref('/users').push().key;
this.database.ref('/users').child(key).set(
///this.assessmentsRef.ref('/users').push(
{
busiName: business.busiName
});
}
ReadAssessment(id: string){
this.assessmentRef = this.db.object('users/' + id);
return this.assessmentRef;
}
ReadAssessmentsList(){
this.assessmentsRef = this.db.list('users/');
return this.assessmentsRef;
}
UpdateAssessments (business: Business){
this.assessmentRef.update({
busiName: business.busiName
});
}
DeleteAssessment(){
this.assessmentRef = this.db.object('users/');
this.assessmentRef.remove();
}
business.ts
export interface Business {
$key: string;
busiName: string;
}
现在您正在使用此创建数据:
const key = this.database.ref('/users').push().key;
this.database.ref('/users').child(key).set({
busiName: business.busiName
});
当您调用 push()
时,Firebase 会生成一个新的唯一位置,这是您 JSON 中以 -M...
开头的键。
该值不是当前用户的 UID,因此这些规则不允许用户读取或写入它:
"users": {
"$uid": {
".write": "$uid === auth.uid";
".read": "$uid === auth.uid";
}
}
相反,您应该使用用户的 UID 作为键将数据写入节点下。那看起来像:
const key = this.database.ref('/users').push().key;
if (firebase.auth().currentUser) {
const key = firebase.auth().currentUser.uid;
this.database.ref('/users').child(key).set({
busiName: business.busiName
});
}
else {
console.error("No current user while trying to write business name");
}