【问题标题】:Firebase Realtime Database xxxx-xxxx-4458' has insecure rules - Followup QuestionFirebase 实时数据库 xxxx-xxxx-4458\' 具有不安全的规则 - 后续问题
【发布时间】:2022-11-14 10:53:19
【问题描述】:

previously asked question 保护 firebase 上的实时数据库。我只使用 Firebase 实时数据库来创建聊天应用程序。用户验证在我们自己的服务器上单独工作,我们没有使用任何 firebase auth 服务进行用户验证。正如Frank van Puffelen 建议的一些官方文档。我现在正在生成 JWT 以根据文档进行授权,但由于我们没有使用 firebase 的任何其他服务,我不确定如何使用生成的 JWT 授权实时数据库。

mAuth.signInWithCustomToken(mCustomToken)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
                // Sign in success

            } else {
                // If sign in fails
                Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
            }
        }
    });

如何验证用户并保护我们的数据库不受世界影响,以便只有应用程序用户才能编辑他们的节点。

我关注了this guide 使用自定义令牌向 Firebase 进行身份验证。

  • 用户使用他们的凭据登录
  • 服务器生成自定义令牌 (JWT)。
  • 按照文档将其传递给signInWithCustomToken
  • 之后呢?对于我的用例,指南位不完整。

编辑:过程:

服务器生成 JWT With PHP Firebase JWT

   $Token = JWT::encode($request_data,$secret_Key,'HS512');

如果用户登录成功,此令牌将返回给应用程序。

成功用户登录后,我使用从服务器收到的自定义令牌调用登录firebase

firebaseAuth = FirebaseAuth.getInstance();
       firebaseAuth.signInWithCustomToken(Session.getJWT())
    .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task)    {             
        if (task.isComplete()){
            Intent intent=new Intent(getActivity(),MainActivity.class);
            getActivity().startActivity(intent); 
            }           
        }   
    });

当用户单击聊天按钮时。检查房间是否已经存在,如果不存在,则为 2 位用户创建一个房间,并使用他们的电话号码,例如9810012345-9810012346

    DatabaseReference db = rebaseDatabase.getInstance().getReference();
      
      
      db.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (dataSnapshot.hasChild(RoomTitle)) {
                    RoomName(RoomTitle, true);
                }else {
                    RoomName(RoomTitle, false);
                }
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });

public void RoomName(String Name, boolean RoomExist) {
    button_SendMessage.setEnabled(true);
    if (!RoomExist) {
        Log.d(TAG, "Room Not Exist Creating One);
        RoomName.put(Name, "");
        FireBaseDatabase.updateChildren(RoomName);
    }

        // Launch Chat Screen

}

然后在聊天屏幕上添加链接问题数据库结构等项目

databaseReference = FirebaseDatabase.getInstance().getReference().child(Room_Name);

所以创建房间,允许读写消息只创建房间,如果房间不属于用户,则阻止访问。我需要为实时数据库设置规则,只有应用程序用户才能访问他们的房间,即使他们是应用程序用户也不能访问其他人(阻止其他应用程序用户潜入其他用户房间)下面是我们的实时数据库结构示例,以便更好地了解我们的 2用户房的样子。我不确定在应用程序方面有很多事情要做,我觉得它比应用程序代码问题更多的是数据库。

【问题讨论】:

    标签: android firebase-realtime-database firebase-security


    【解决方案1】:

    一旦您对 signInWithCustomToken 的调用成功,每当 Firebase 实时数据库 SDK 连接时,该令牌将被传递到服务器,然后将对其进行验证并传递给您的安全规则中的 auth 变量。

    所以你可以检查request comes from a signed-in user是否有:

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

    不过,这有点宽泛,因此您需要将其缩小到特定用户。例如,您可以 allow only a content-owner access 使用:

    {
      "rules": {
        "some_path": {
          "$uid": {
            // Allow only authenticated content owners access to their data
            ".read": "auth !== null && auth.uid === $uid",
            ".write": "auth !== null && auth.uid === $uid"
          }
        }
      }
    }
    

    您在 JWT 中的任何声明也将在 auth.token variable 下的安全规则中可用。

    【讨论】:

    • 感谢您的快速回答。我将尝试实现它,看看它是否有效。再次感谢。 :)
    • 我正在尝试使用自定义令牌的指南,我需要将我们的 JWT 密钥交给 Firebase 进行解码吗?在文档中没有太多关于像我们这样的自定义验证的信息。有什么方法可以调试对数据库的调用,其中可以包含 JWT 和其他信息交换等数据?
    • 当您调用 signInWithCustomToken 时,您将令牌传递给 Firebase。一旦成功,该令牌就会通过 SDK 的每个 API 调用传递给数据库安全规则。 --- 此后没有任何特定于自定义令牌的内容,因为来自您的令牌的所有信息都在 auth.token 变量中可用 - 就像 Firebase 的内置提供程序铸造的令牌一样。 --- 为了使调试令牌信息更容易,您可以使用模拟器:显示更多信息:firebase.google.com/docs/emulator-suite
    • 当用户登录我们的应用程序时,我的应用程序在服务器上生成令牌,我们将该令牌保留在应用程序端以进行 API 验证,并且在用户成功登录 signInWithCustomToken 后,我将相同的令牌传递给 firebase。在稍后阶段,每当用户想要通过DatabaseReference db = FirebaseDatabase.getInstance().getReference(); 发起聊天(连接实时数据库)所以这个带有后缀的调用会为每 2 个用户添加唯一的房间。我能够使用规则验证 JWT(任何人都可以生成随机 JWT 令牌),无论它是否来自经过验证的用户。
    • 如果您想验证 ID 令牌是否由您自己的代码创建,请在令牌中找到 include a custom claim,然后您可以在 auth.token 中找到它。 --- 如果在所有这些之后您仍然无法使其正常工作,请使用(更新的)代码提供您的问题的更新,说明您如何铸造令牌(带有自定义声明)以及如何检查该声明在安全规则中。
    猜你喜欢
    • 2018-08-27
    • 2021-01-14
    • 2021-06-20
    • 2021-12-05
    • 2020-08-08
    • 2019-01-30
    • 1970-01-01
    • 2020-12-28
    相关资源
    最近更新 更多