Help us understand the problem. What is going on with this article?

Firebase Auth のユーザ認証機能を自前のデータベースと連携する

More than 1 year has passed since last update.

認証だけfirebase使いたい場合の考察。

要求

  • ユーザ認証(登録・ログイン)はfirebaseに任せたい。
  • ユーザデータはAWS RDS等別途のシステムで管理したい。

全体像

  1. Firebase <-> client ... ユーザ登録・ログイン(アクセストークンの発行)
  2. client -> self-backend ... アクセストークンの送信
  3. self-backend <-> Firebase ... アクセストークン検証、uid(firebase user ID)の確認
  4. self-backend -> client ... 認証可否含めたレスポンスの返却

詳細

1. Firebase <-> client ... ユーザ登録・ログイン(アクセストークンの発行)

  • firebaseとclient間のみのやりとりでユーザ認証をしアクセストークンを得る
  • ドキュメント通り実装する https://firebase.google.com/docs/auth/?hl=ja
    • 必要なプロバイダー(facebook, twitter, emailなど)毎の実装
    • ios/android/webどれでも対応可能

2. client -> self-backend ... アクセストークンの送信

  • 認証完了した際に得られるアクセストークンを自サービスのbackendに投げる
  • 自前backendにリクエストする際にAuthorization: Bearer {TOKEN}httpヘッダつけるのが素直な実装か。
  • その際、アクセストークンはclientプログラムで保持せず、毎回getTokenを使うとリフレッシュ等自動でやってくれる(はず)

3. self-backend <-> Firebase ... アクセストークン検証、uid(firebase user ID)の確認

// token の検証をしてuidを返す
function verifiedUid($idTokenString)
{
    if (empty($idTokenString)) {
        return '';
    }
    // firebase管理画面からadmimn jsonをDL、配置しておく
    $firebaseServiceJson = json_decode(file_get_contents('path/to/firebase/admin/sdk/settings.json'));
    // PSR16 Simple Cacheの実装であれば他のでも大丈夫そう。firebaseのpublic keyをキャッシュする用
    $cache = new \Symfony\Component\Cache\Simple\FilesystemCache();
    $keyStore = new \Firebase\Auth\Token\HttpKeyStore(null, $cache);
    $verifier = new \Firebase\Auth\Token\Verifier($firebaseServiceJson->project_id, $keyStore);

    $uid;
    try {
        $verifiedIdToken = $verifier->verifyIdToken($idTokenString);
        $uid = $verifiedIdToken->getClaim('sub'); // "uid"

        // なんらかのキャッシュ機構を使って毎回firebaseにverifyしないようにする方が良さそう
        $exp = $verifiedIdToken->getClaim('exp'); // expr

    } catch (\Firebase\Auth\Token\Exception\ExpiredToken $e) {
        var_dump($e);
    } catch (\Firebase\Auth\Token\Exception\IssuedInTheFuture $e) {
        var_dump($e);
    } catch (\Firebase\Auth\Token\Exception\InvalidToken $e) {
        var_dump($e);
    }

    return $uid;
}
  • 得られたuidはfirebase project単位でのユニーク値なので、この値を元に自前db等でデータ管理する。uidでの登録がなければ新規ユーザエントリ生成。あれば既存ユーザのログインとなる。
  • MySQLでのシンプルなテーブル例。uidの不可逆圧縮はした方が良いだろうか。した方がよりセキュアではある。
CREATE TABLE `users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `uid` varchar(255) NOT NULL DEFAULT '',
  `nickname` varchar(255) NOT NULL DEFAULT '',
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uid` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

4. self-backend -> client ... 認証可否含めたレスポンスの返却

  • 3. に成功してればログイン済みユーザとなるし、そうでなければゲスト扱い。通常の会員サービスと変わらない

その他諸々

AWS Cognitoは?

Cognitoでも同じことできるだろうけど、用語も実装もfirebaseの方がわかりやすかったので未確認

利用料

2018.8現在のところ電話番号認証は1万/月まで無料。それ以降は有料プラン https://firebase.google.com/pricing/?hl=ja
それ以外のAuth機能は無料。
AdminSDK利用とかもしかしたら抜けてるポイントがあるかも?

instagram や自作認証機構、他のプロバイダーを使う。

カスタム認証を使って作る
https://firebase.google.com/docs/auth/ios/custom-auth
https://developers-jp.googleblog.com/2016/10/authenticate-your-firebase-users-with.html
https://github.com/search?q=firebase+instagram

firestoreやcloud sqlを使えば

この辺使うとするとgceやcloud functionも必要になってきそうで、S3やTranscoderやもろもろ乗り換える必要が出てきそうで、なかなか手が出ない。心理的ロックイン感。

データにより分けるのは良いかもしれない。ログやマスタデータのみfirestoreとかすると、firebaseの管理画面から閲覧修正できるので便利かも。

geerpm
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした