スマホアプリ開発を加速する,Firebaseを使ってみよう

第5回 Firebaseのデータをセキュアに保つ

この記事を読むのに必要な時間:およそ 4 分

前回までで,Firebase上にさまざまな方法でデータを保存し,用途に合わせたいろいろなコールバックを使ってデータを読み出す方法を学んできました。簡単なアプリならばこれまでの知識で十分作ることができますが,今回はサービスを安全に提供する上で欠かすことのできない「セキュリティ」について解説して行きたいと思います。

今回も,前回の連載に引き続き,例としてリアルタイムチャットサービスを取り上げます。

Firebaseを適切に設定することで,

  • メールアドレスとパスワードを使ってログイン処理を行う
  • チャットメッセージは適切にログインしたユーザしか閲覧もメッセージの投稿もできない

といったよくある機能を簡単に実現することができます。

ユーザ認証とアクセス制御

Authentication(認証)

「セキュリティ」を考える場合に,そのユーザが「誰であるのか」を確認することは不可欠です。 ⁠誰であるのか」がわかって初めて,

  • 「Aさんは /messages/01 を閲覧できる」
  • 「Bさんは /messages/02 を閲覧・書き込みできる」

といったアクセス制御が可能です。

この「誰であるのかを確認する」作業をAuthentication(認証)と言います。

Firebaseは次の表にある認証方法を提供しており,アプリに柔軟な認証機能を簡単に組み込むことができます。

認証の種類概要
大手SNS認証Facebook, GitHub, Google, Twitter アカウントを使った認証
パスワード認証Firebase自身にEメール,パスワードを登録し,それを使った認証
匿名ログイン一時的な匿名ログイン
カスタムログイントークンすでに自前で持っている認証基盤との連携

今回は,Firebase自身にEメール,パスワードを登録して,それを使ってユーザ認証を試してみます。

今後の連載中では,実践テクニックとしてTwitterアカウントを使った認証もご紹介する予定ですので,楽しみにしてください。

Authorization(認可)

ユーザ認証によって,そのユーザが「誰であるか」がわかり,したがって「何をすることができ,どこにアクセスすることができる」というようなことがわかります。こういった情報をAuthorization(認可)と呼びます。

Firebaseではこの認可情報でユーザを識別し,⁠アカウントダッシュボード」「Firebase Rules」と呼ばれる設定ルールに従って細やかなアクセス制御を実現することができます。

たとえば,以下のルールは/fooは誰でも閲覧できるが,書き込みはできない」という意味になります。詳しくは本連載で解説して行きたいと思います。

{
  "rules": {
    "foo": {
      ".read": true,
      ".write": false
    }
  }
}

パスワード認証

今回の連載では,Firebase自身にEメール,パスワードを登録する「パスワード認証」を利用します。

パスワード認証を利用するには,ダッシュボードから「Login & Auth」を選択し,⁠Enable Email & Password Authenticaion」にチェックを入れます。

図1 Enable Email & Password Authentication

図1 Enable Emai

これで準備は整いました。

さっそくFirebase上にユーザを作成するコードを見て行きましょう。

ユーザの作成

まずは以下のコードを実行してみてください。

Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");

ref.createUser("fu.shiroyama@gmail.com", "abcd1234", new Firebase.ValueResultHandler<Map<String, Object>>() {
    @Override
    public void onSuccess(Map<String, Object> result) {
        Log.d(TAG, "Successfully created user account with uid: " + result.get("uid"));
    }
    @Override
    public void onError(FirebaseError firebaseError) {
        Log.d(TAG, "error: " + firebaseError.getMessage());
    }
});

まず,1行目でFirebaseのルート参照を取得します。

次に,ユーザを作成するためにcreateUser()メソッドを呼び出します。createUser()は第1引数にEメールアドレス,第2引数にパスワードを取ります。

認証の結果は,第3引数のFirebase.ValueResultHandlerインタフェースで受け取ることができます。成功した場合はonSuccess()の第1引数に認証結果がMap形式で渡されます。ここではユーザを一意に識別するuidを取得しています。

以下のようにログ出力されれば成功です。

D/Firebase: Successfully created user account with uid: 17613df6-4d51-4148-9adf-e948c6699b53

失敗した場合はonError()の第1引数にFirebaseError形式でエラーが渡されます。FirebaseErrorからはgetMessage()getDetail()でエラー理由を取得することができます。

たとえば,すでに存在するユーザをもう一度作成しようとした場合は,以下のようにエラー出力されます。

D/Firebase: error: The specified email address is already in use.

登録済みユーザはダッシュボードから確認することができます。

図2 Registered Users

図2 Registered Users

uid

このuidは,Firebaseが提供するさまざまな認証方法によらず,一意であることが保証されています。同じEメールアドレスとパスワードを使ったとしても,⁠Twitter認証」「Facebook認証」といった具合に認証プロバイダが異なれば,きちんと違うユーザと見なされますので,ここで取得できるuidをアプリで一意なユーザのユニークキーとして利用するのは正しい使い方です。

著者プロフィール

白山文彦(しろやまふみひこ)

サーバサイド,インフラ,Androidなど何でもやるプログラマ。

コメント

コメントの記入