4. チュートリアル2 : ログイン機能とアクセス制御

チュートリアル2では、チュートリアル1の Todo アプリにユーザ登録・ログイン機能を追加します。

チュートリアル1ではデータを全員で共有していましたが、 チュートリアル2ではユーザごとにデータを管理するようにします。

4.1. サンプルの実行

チュートリアル1と同じように、デベロッパコンソールからアプリケーションを新たに作成し、 Consts.java に設定を行って下さい。

また、デベロッパコンソールから、オブジェクトバケットを作成します。 バケット名は “TodoTutorial2” としてください。 なお、ACL はデフォルトのまま (認証ユーザのみ読み書き可能)で構いません。

アプリを起動すると、ログイン画面が表示されます。 最初にサインアップボタンを押してサインアップ画面に遷移して下さい。 E-mail アドレスとパスワード(8文字以上)を入力してサインアップします。

サインアップが完了したらログインを行って下さい。 チュートリアル1と同様のアプリ画面が表示されます。 データを入れたら、メニューからログアウトしてください。

ログイン画面に戻りますので、今度は違うユーザ名でサインアップを行い、ログインしてみてください。 先ほど作成したデータが、現在のユーザからは見えなくなっていることを確認してください。

4.2. サインアップ

サインアップは SignupActivity クラスで行っています。

// サインアップ処理

// ユーザオブジェクト生成
NbUser user = new NbUser(mService);

// Emailを登録
user.setEmail(email);

// サインアップ
user.register(password, new NbUsersCallback() {
    @Override
    public void onSuccess(List<NbUser> users) {
        showAlert("User registered");

        // ログイン画面のアクティビティに遷移
        Intent intent = new Intent(SignupActivity.this, LoginActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    }

    @Override
    public void onFailure(int status, NbErrorInfo errorInfo) {
        showAlert("signup failed : " + status);
    }
});

サインアップを行うには、NbServiceからNbUserを取得し、メールアドレスを設定後、 register()を呼び出します。

サインアップが成功すると、onSuccess()が呼ばれます。 ここでログイン画面に遷移します。

4.3. ログイン

ログインは LoginActivity クラスで行っています。

4.3.1. ログイン処理

// ログイン処理
NbUser.login(null, email, password, new NbUsersCallback() {
    @Override
    public void onSuccess(List<NbUser> users) {
        // メインアクティビティに遷移
        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
        dismissProgressDialog();
    }

    @Override
    public void onFailure(int status, NbErrorInfo errorInfo) {
        showAlert("login failed : " + status);
        dismissProgressDialog();
    }
});

ログインを行うには、NbUser.login() を呼び出します。

ログインが成功すると、onSuccess() が呼ばれます。 ここでアプリ本体に遷移します。

4.4. アプリ本体

アプリケーション本体はチュートリアル1と同様に MainActivity クラスに記述しています。

チュートリアル2では、チュートリアル1の実装に、ログイン関連の処理を追加しています。

4.4.1. ログインチェック

/**
 *  初期化処理
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // NbService インスタンスを取得
    mService = MainApplication.getInstance().getNebulaService();

    // ログイン状態チェック
    if (!NbUser.isLoggedIn(mService)) {
        // 未ログインの場合はログイン画面のアクティビティへ遷移
        Intent intent = new Intent(this, LoginActivity.class);
        startActivity(intent);
        finish();
        return;
    }
    setContentView(R.layout.activity_login);
}

onCreate() 内でログイン済みかどうかチェックを行います。

NbUser.isLoggedIn() を呼び出してユーザのログイン状態をチェックし、 未ログインの場合はログイン画面に遷移します。

4.4.2. ログアウト処理

// ログアウト処理
NbUser.logout(new NbUsersCallback() {
    @Override
    public void onSuccess(List<NbUser> users) {
        // ログイン画面のアクティビティに遷移
        Intent intent = new Intent(MainActivity.this, LoginActivity.class);
        startActivity(intent);
        finish();
        return;
    }

    @Override
    public void onFailure(int status, NbErrorInfo errorInfo) {
        showAlert("logout failed : " + status);
    }
});

NbService.user().logout() を呼び出してログアウトを行います。

ログアウトが成功すると、 onSuccess() が呼ばれます。 ここでログイン画面に遷移します。

4.4.3. 保存データのアクセス制御

データの保存処理は addTodo() で行っており、処理はチュートリアル1と全く同じです。

ただし、ログイン状態で作成したデータには、そのユーザのみがアクセス可能な ACL が 自動的に設定されます。具体的には以下のような ACL が設定されます。

{
    owner: "オーナのユーザID",
    r: [], w: [], c: [], u: [], d: [], admin: []
}

このため、他のユーザが作成したデータは、同一のバケットに入っていても不可視になります。 また、変更することもできません。

なお、チュートリアル1のように未ログイン状態でデータを作成した場合は、 以下のように誰でも読み書き可能な ACL が自動的に設定されます。

{
    r: ["g:anonymous"], w: ["g:anonymous"], c: [], u: [], d: [], admin: []
}