Flutter模拟Firebase安全规则插件fake_firebase_security_rules的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter模拟Firebase安全规则插件fake_firebase_security_rules的使用

标题

fake_firebase_security_rules

内容

This project simulates Firebase Security Rules. It is meant to be used by Fake Cloud Firestore and Firebase Storage Mocks. Given these request inputs:

  • Firebase security rules such as:

    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{userId} {
          allow read, write: if request.auth != null && request.auth.uid == userId;
        }
      }
    }
    
  • Concrete path, access method, eg an update on /databases/some-db/users/abcd

  • Variables, eg a Map such as { 'request': { 'auth': { 'uid': 'efgh' } } }

the library computes whether the request should be allowed or not.

使用示例

import 'package:fake_firebase_security_rules/fake_firebase_security_rules.dart';

// https://firebase.google.com/docs/rules/rules-and-auth#leverage_user_information_in_rules
final authUidDescription = '''
service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}''';

void main(List<String> args) async {
  final securityRules = FakeFirebaseSecurityRules(authUidDescription);
  final uid = 'a57293b';
  final variables = {
    'request': {
      'auth': {'uid': uid}
    }
  };
  
  // Prints out `true`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/users/$uid', Method.read,
      variables: variables));
  
  // Prints out `false`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/users/someone-elses-id', Method.read,
      variables: variables));
  
  // Prints out `false`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/somewhere-else/someone-doc',
      Method.read,
      variables: variables));
}

See the Unit tests for more advanced examples of usage.

特性

Supports:

  • rules declarations used in Firestore and Firebase Storage.
  • recursive match definitions.
  • exhaustive path matching with path variables and wildcards, eg /users/{userId}/{documents=**}.
  • request.auth object populated with uid, custom claims…
  • standard CEL types and methods, eg bool, int, double, String, Map, List, String.match(regexp), a in list… See cel-dart’s supported features for an exhaustive list.

Missing:

  • timestamps.
  • durations.
  • custom functions.
  • resource object.
  • request.resource object.
  • exists(), get() functions.

实现细节

Differences between Firebase Rules CEL and standard CEL:

  • Timestamps. Although not implemented in this project yet, Firebase Rules uses its own Timestamp implementation while CEL uses google.protobuf.Timestamp (spec).

How the project works:

  • FirestoreRules.g4 describes a grammar that parses security rules into Matches. A Match contains a path, made up of segments. Some segments might be variables or wildcards. The expression at the right of allow statements is in Common Expression Language (CEL). CEL is a language used by many security projects. See the CEL specs.

Working on the grammar:

  • The fastest way to get your environment up and running is to create a Codespace on the repository, then pip install antlr4-tools. Once this is done, you can run antlr4-parse to try out the rules against some inputs and antlr4 to regenerate the Parser in lib/src/parser/gen.

Generating the parser:

  • If you modify FirestoreRules.g4, you may want to regenerate the parser:
    cd grammar
    ./regenerateParser.sh
    

示例代码

import 'package:fake_firebase_security_rules/fake_firebase_security_rules.dart';

// https://firebase.google.com/docs/rules/rules-and-auth#leverage_user_information_in_rules
final authUidDescription = '''
service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, write: if request.auth != null &amp;&amp; request.auth.uid == userId;
    }
  }
}''';

void main(List<String> args) async {
  final securityRules = FakeFirebaseSecurityRules(authUidDescription);
  final uid = ' a57293b';
  final variables = {
    'request': {
      'auth': {'uid': uid}
    }
  };

  // Prints out `true`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/users/$uid', Method.read,
      variables: variables));

  // Prints out `false`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/users/someone-elsses-id', Method.read,
      variables: variables));

  // Prints out `false`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/somewhere-else/someone-doc',
      Method.read,
      variables: variables));
}

更多关于Flutter模拟Firebase安全规则插件fake_firebase_security_rules的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter模拟Firebase安全规则插件fake_firebase_security_rules的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用fake_firebase_security_rules插件来模拟Firebase安全规则的示例代码。这个插件可以帮助开发者在本地环境中测试Firebase安全规则,而无需连接到实际的Firebase数据库。

首先,确保你的Flutter项目已经添加了fake_firebase_security_rules依赖。在pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  fake_firebase_security_rules: ^latest_version  # 请替换为最新的版本号

然后,运行flutter pub get来安装依赖。

接下来,我们来看一个具体的代码示例,展示如何使用fake_firebase_security_rules来模拟Firebase安全规则。

import 'package:flutter/material.dart';
import 'package:fake_firebase_security_rules/fake_firebase_security_rules.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Firebase Security Rules Simulation',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SecurityRulesSimulationScreen(),
    );
  }
}

class SecurityRulesSimulationScreen extends StatefulWidget {
  @override
  _SecurityRulesSimulationScreenState createState() => _SecurityRulesSimulationScreenState();
}

class _SecurityRulesSimulationScreenState extends State<SecurityRulesSimulationScreen> {
  final FakeFirebaseSecurityRules _fakeSecurityRules = FakeFirebaseSecurityRules();

  String _result = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Firebase Security Rules Simulation'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              decoration: InputDecoration(
                labelText: 'Enter your Firebase rule (JSON format)',
              ),
              maxLines: 10,
              keyboardType: TextInputType.multiline,
              onChanged: (String rules) {
                setState(() {
                  _applyRules(rules);
                });
              },
            ),
            SizedBox(height: 20),
            Text(
              'Simulation Result:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 10),
            Text(
              _result,
              style: TextStyle(fontSize: 16),
            ),
          ],
        ),
      ),
    );
  }

  void _applyRules(String rules) {
    // 解析规则(假设规则是以JSON字符串形式输入的)
    try {
      final Map<String, dynamic> ruleMap = jsonDecode(rules);
      _fakeSecurityRules.setRules(ruleMap);

      // 模拟一个读操作
      final Map<String, dynamic> readData = {
        'path': '/users/userId123',
        'auth': {
          'uid': 'authenticatedUid456',
        },
      };
      final bool readAllowed = _fakeSecurityRules.simulateRead(readData);
      _result = 'Read allowed: $readAllowed';

      // 模拟一个写操作
      final Map<String, dynamic> writeData = {
        'path': '/users/userId123',
        'newData': {'name': 'John Doe'},
        'auth': {
          'uid': 'authenticatedUid456',
        },
      };
      final bool writeAllowed = _fakeSecurityRules.simulateWrite(writeData);
      _result += '\nWrite allowed: $writeAllowed';

    } catch (e) {
      _result = 'Invalid JSON or rule syntax error: ${e.toString()}';
    }
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,用户可以在其中输入Firebase安全规则的JSON字符串。然后,我们使用fake_firebase_security_rules插件来模拟读和写操作,并显示结果。

请注意,fake_firebase_security_rules插件的API可能会随着版本更新而变化,因此请参考插件的官方文档以获取最新和详细的用法。此外,上述代码仅用于演示目的,实际项目中可能需要根据具体需求进行调整。

回到顶部