You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase实时数据库自定义JWT认证后如何配置房间级安全规则

实时数据库安全规则配置方案(自定义Auth聊天应用)

问题背景

基于Firebase实时数据库开发聊天应用,用户验证通过自有服务器完成,未使用Firebase Auth原生服务。已按照Frank van Puffelen的建议生成JWT并通过自定义Token完成Firebase Auth登录,现需配置数据库规则,确保用户仅能读写自己参与的聊天房间(房间ID格式如9810012345-9810012346,为两个用户ID拼接而成),禁止访问不属于自己的房间。

当前完整流程

  • 用户通过自有凭证登录,服务器使用PHP Firebase JWT生成JWT:
$Token = JWT::encode($request_data,$secret_Key,'HS512');

登录成功后将Token返回给应用。

  • 应用调用Firebase Auth接口完成登录:
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); 
            }           
        }   
    });
  • 用户点击聊天按钮时,检查房间是否存在,不存在则创建:
DatabaseReference db = FirebaseDatabase.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");
        Map<String, Object> RoomNameMap = new HashMap<>();
        RoomNameMap.put(Name, "");
        FirebaseDatabase.getInstance().getReference().updateChildren(RoomNameMap);
    }

    // Launch Chat Screen
}
  • 进入聊天界面后关联对应房间的数据库节点:
databaseReference = FirebaseDatabase.getInstance().getReference().child(Room_Name);

数据库规则配置

核心思路

利用房间ID的格式特征(两个用户ID用-拼接),在规则中验证当前登录用户的UID是否为房间ID中的其中一个用户ID,以此限制读写权限。

规则代码

{
  "rules": {
    "$roomId": {
      ".read": "auth != null && ($roomId.split('-')[0] == auth.uid || $roomId.split('-')[1] == auth.uid)",
      ".write": "auth != null && ($roomId.split('-')[0] == auth.uid || $roomId.split('-')[1] == auth.uid)"
    }
  }
}

关键说明

  1. JWT字段要求:生成JWT时,必须将用户的自有唯一标识(如示例中的9810012345)设置为JWT的uid字段,确保Firebase Auth登录后auth.uid能正确映射到用户的自有ID。例如PHP中$request_data需包含:
$request_data = [
    "uid" => "用户自有唯一ID",
    // 其他必要声明
];
  1. 权限验证逻辑:规则先检查用户已登录(auth != null),再通过split('-')分割房间ID,判断当前用户UID是否为房间的两个参与者之一,符合条件则允许读写。
  2. 房间创建权限:当前流程中直接在根节点创建房间,上述规则已覆盖创建场景——用户创建房间时,$roomId为目标房间名,规则会验证用户是否为房间参与者,符合条件则允许创建。

内容的提问来源于stack exchange,提问作者androidXP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:30:52