この記事は、Firebase Advent Calendar 2019の13日目の記事です。
Firebase Cloud Storageのセキュリティルール書き方のサンプルです。
Firestoreのセキュリティルールは度々書いていたのですが、Firebase Cloud Storageのセキュリティルールはあまり書いてなかったなと思い立ち調べみました
基本
基本的な構文はFirestoreのセキュリティルールと変わりません。
異なる点としては、制御できる権限がデータ追加のwrite
とデータ閲覧のread
のみです。
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
ユーザー認証
認証の有無によるアクセス制限
Firebase Authenticationが参照できるため、authの有無で判別可能です
// 認証済みユーザーのみ閲覧可能
match /internal/{imageId} {
allow read: if request.auth != null;
}
// 自分のuserIdに属するbucketのみ閲覧可能
match /user/{userId}/{imageId} {
allow read: if request.auth.uid == userId;
}
ユーザーの属性によるアクセス制限
Firebase Cloud Storageのセキュリティルールの中からFirestoreの情報にアクセスすることは出来ません。
なので、Firestoreのセキュリティルールのようにget関数でユーザードキュメントを参照して、、、という記述は不可です。
もし、ユーザーのロールに合わせた権限を設定したい場合は、Firebase Autenticationのカスタムクレームを使って設定した値から参照しましょう。
// 事前にFirebaseFunctionsのフックなどでAuth userの追加時に、admin, groupIDのカスタムクレームを設定している前提
// admin権限をもつユーザーのみ閲覧、書き込みできる
match /files/admin/{fileName} {
allow read, write: if auth.token.admin === true;
}
// 特定のグループに属するユーザーのみ閲覧出来る
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
}
ファイルのバリデーション
パス名や、request.resource
とresource
を参照することでファイルサイズや種別など様々なバリデーションが行えます。
request.resource
は新たに追加されるファイルの参照で、resource
は既に同名のパスにあるファイルの参照です。
ファイル名での制限
パスからファイル名を参照してファイル名のバリデーションが可能です。(この場合だと、{fileName}
)
// ファイル末尾が.txtのファイルのみ追加可能とする
match /text/{fileName} {
allow write: if fileName.matches('.*\\.txt')
}
// ファイル名が30文字未満のファイルのみ追加可能とする
match /images/{fileName} {
allow write: if fireName.size() < 30
}
上書き制限
resource
を参照することで同名のファイルがある場合の書き込み制限が可能です。
// 同名のファイルがない場合のみ追加可能
match /{imageId} {
allow write: if resource == null
}
サイズでの制限
request.resource.size
でデータのサイズを取得できます。
// 5MB以下のみ追加可能とする
match /{imageId} {
allow write: if request.resource.size < 5 * 1024 * 1024
}
種別での制限
request.resource.contentType
でデータの種別を取得できます。
// image/pngのみ追加可能とする
match /png/{imageId} {
allow write: if request.resource.contentType == 'image/png'
}
// image/*のみ追加可能とする
match /image/{imageId} {
allow write: if request.resource.contentType.match("image/.*")
}
終わりに
以上、Firebase Cloud Storageのセキュリティルール書き方一覧でした。
次回自分で使うときには、こちらも設定していこうかなと思います。
参考