Custom Claimとは
Authenticationの認証で利用するユーザー属性に独自の情報を追加できるものと理解しています。
例えば、下記のようにuidを指定して属性をセットすると、
admin.auth().setCustomUserClaims(uid, {admin:true}).then()
ユーザーチェックの際に、下記のように利用できます。
firebase.auth().onAuthStateChanged(user => {
if(user){
user.getIdTokenResult(true).then((result) => {
if(result.claims.admin === true){
//admin処理
}
}
}
})
また、firestore等のルールの中で、
allow read, wirte: if request.auth.token.admin == true;
といった感じで利用できるようになります。
多くの場合管理者とユーザーの区別等に利用されますが、もちろんadminというキーワード以外も利用できます。
Custom Claimの制限
Custom Claimにはいくつかの制限というか条件があります。
admin権限でしか利用できないので実運用ではfunctionsと組み合わせて利用することになるでしょう。
- admin権限じゃないと付与・管理できない(クライアントライブラリからは操作できない)
- 1000バイト以下
Custom Claimの設定
では実際に設定してみます。
ここではuid直設定していますが、実際はプログラム中で取得することになるでしょう。
functionを作ればuidを引数で受けとるとか。
const admin = require('firebase-admin');
const serviceAccount = require('/path/to/key.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://test-xxxxx.firebase.com'
});
const uid = "2E6OjMO6uVT3QilaibPC7mosc1x2";
admin.auth().setCustomUserClaims(uid, { admin: true, premium: true }).then(() => {
console.log("set customClaim");
})
Custom Claimの利用
クライアントで使う場合、例えば下記のようにします。
const firebase = require('firebase');
//環境に合わせて
const firebaseConfig = {
apiKey: "AIzaSyD7HtQGZhfL4T1ttrElxsgDwqolAWxxxxx",
authDomain: "test-xxxxx.firebaseapp.com",
databaseURL: "https://test-xxxxx.firebaseio.com",
projectId: "test-xxxxx",
storageBucket: "test-xxxxx.appspot.com",
messagingSenderId: "250622200000",
appId: "1:250622212741:web:ff33a2e77b61e8990xxxxx",
measurementId: "G-VVQ2BXXXXX"
};
firebase.initializeApp(firebaseConfig);
( async ()=>{
await firebase.auth().signInWithEmailAndPassword("test@test.com","testtest");
const result = await firebase.auth().currentUser.getIdTokenResult(true);
console.log(result.claims);
})()
user直下にはなく、getIdTokenResult()で取得しなければならないようです。
下記のような結果が得られます。admin, premiumが設定されています。
{
admin: true,
premium: true,
iss: 'https://securetoken.google.com/staging-a5946',
aud: 'staging-a5946',
auth_time: 1575931924,
user_id: '2E6OjMO6uVT3QilaibPC7mosc1x2',
sub: '2E6OjMO6uVT3QilaibPC7mosc1x2',
iat: 1575931925,
exp: 1575935525,
email: 'test@test.com',
email_verified: false,
firebase:
{ identities: { email: [Array] }, sign_in_provider: 'password' } }
実際にはif(result.claims.admin){}というような感じで利用することになります。
Custom Claimの削除
nullをsetするといいみたいです。
admin.auth().setCustomUserClaims(uid, { admin: null, premium: null })
Custom Claimを利用するか普通のdocumentを使うか
多くの場合、SignUp時にAuthenticationへの(自動)登録と同時に普通のfirestore等にもデータを書き込みます。認証時にそちらを利用することもできますが、Custom Claimを使うPros, Consとしては、下記のような感じかなと。
Pros
- 認証の一部として使える
- dbへのアクセスが発生しないためオーバーヘッドが少ない、ミスが無い、read費用が発生しない
Cons
- admin権限が必要(逆に言えば安全)。設定用のfunctionsを設定する必要がある。
- 1000バイト以上の情報が持てない