Authoring Security Rules
Security rules allow you to control data access permissions. Through flexible rule syntax, different granularities of read-write control combinations can be implemented on collections or buckets.
Default Rules
By default, security rules deny all data access.
{}
User Identity Authentication
When an authenticated user makes a request, the system populates the auth
variable with the user's unique id uid
and login method loginType
. When an unauthenticated user makes a request, the auth
variable is null
.
Through the auth
variable, file access can be controlled based on identity using the following common methods:
- Public: The
auth
value is not evaluated. - Accessible only to logged-in users: Check that
auth
is notnull
. - User-private: Check if
auth.uid
equals the resource'sopenid
. - For a specific login method: Restrict access to anonymously logged-in users by checking that
auth.loginType
is notANONYMOUS
Public
Any rule that does not consider auth
can be regarded as a public
rule, as it disregards the user's authentication context. These rules are well-suited for scenarios involving the presentation of public data (static resource content).
- Cloud Database
- Cloud Storage
{
"read": "doc._openid != null"
}
{
"read": "resource.openid != null"
}
Accessible to logged-in users
In some cases, you may want to restrict access to user data to only logged-in users. For example, only logged-in users can view discussions in the forum. Since the auth
variable is null
for all unauthenticated users, you can set the following rules:
{
"read": "auth != null"
}
Readable by all users, writable only by the creator and administrators
- Cloud Database
- Cloud Storage
Data records the owner user ID of the current data via _openid
{
"read": true,
"write": "doc._openid == auth.openid", // Login method is WeChat.
"write": "doc._openid == auth.uid" // Login method is not WeChat.
}
{
"read": true,
"write": "resource.openid == auth.openid", // Log-in method is WeChat.
"write": "resource.openid == auth.uid" // Log-in method is not WeChat.
}
Readable and writable only by the creator and administrators
- Cloud Database
- Cloud Storage
Data records the owner user ID of the current data via _openid
{
"read": "doc._openid == auth.openid", //Login method is WeChat.
"read": "doc._openid == auth.uid", // Log-in method is not WeChat.
"write": "doc._openid == auth.openid", //Login method is WeChat.
"write": "doc._openid == auth.uid" // Login method is not WeChat.
}
{
"read": "resource.openid == auth.openid", //Log-in method is WeChat.
"read": "resource.openid == auth.uid", // Log-in method is not WeChat.
"write": "resource.openid == auth.openid", // Log-in method is WeChat.
"write": "resource.openid == auth.uid" // Log-in method is not WeChat.
}
Readable by all users, writable only by administrators
{
"read": true,
"write": false
}
Readable and writable only by administrators
{
"read": false,
"write": false
}
Data Validation
You can use security rules to conditionally write new data based on existing data in the database or storage partition. You can also write rules to enforce data validation by restricting write operations based on the new data being written.
Limitations on New Data
- Cloud Database
- Cloud Storage
If you want to ensure that documents containing specific fields have not been created yet. For example, if you want to reject the creation of all documents containing the ranking field, you can prohibit it in the create condition.
{
// ... //
"create": "request.data.ranking == undefined"
}
All uploaded files must have an ownership value and belong to the current user.
{
// ... //
"write": "resource.openid == auth.openid"
}
Using Existing Data
Many applications store access control information as fields within documents in the database. Security rules can control access based on document data attributes:
To implement this access control, corresponding attributes must be defined in the user data. Security rules inspect requests based on data attributes to determine whether to allow or deny them. For example, when storing grades, different access levels can be assigned to distinct user groups: grant read-only permission to the "student" group, and grant read-write permission for the subjects they teach to the "teacher" group. The user table (user collection) can be designed with the following structure:
{
userID: string, // Unique user id
role: string, // STUDENT, TEACHER,
projects: string[] // Subjects taught by the teacher
}
Score table (score) is designed as follows:
{
studentID: string,
project: string,
score: number
}
The rules for the score table can be set as:
{
"read": "get(`database.user.${auth.uid}`).role == 'STUDENT' || (get(`database.user.${auth.uid}`).role == 'TEACHER' && doc.project in get(`database.user.${auth.uid}`).projects)",
"write": "get(`database.user.${auth.uid}`).role == 'TEACHER' && doc.project in get(`database.user.${auth.uid}`).projects"
}