69
46

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FirebaseのCustom Claimを利用する

Last updated at Posted at 2019-12-09

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バイト以上の情報が持てない

参考

69
46
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69
46

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?