Kotlinでログイン機能をつけてみよう！

# 【Kotlin×mBaaS】シリーズ概要
* Kotlinで[ ニフクラ mobile backend ](http://mbaas.nifcloud.com/)(通称：mBaaS)を使ってKotlinで開発を始めたい人向けのドキュメントです。
* [ニフクラ mobile backend のAndroid(Java SDK)用ドキュメント](http://mbaas.nifcloud.com/doc/current/index.html)を__Kotlin__用に書き換えて動かしてみたものをまとめました。
* 初心者でもわかりやすいよう心掛けて作っていますが、わかりにくい部分がありましたらコメントをいただければ訂正しますのでお気軽にご意見をお願いします。
* 今回は__＜会員管理編＞__です！

# 事前準備のお願い
* 事前に ニフクラ mobile backend の登録とアプリの新規作成をし、 [KotlinでmBaaSを始めよう！](https://qiita.com/nifcloud_mb/items/5b6290977f3147c3bc4f)をご覧いただき、必要な初期設定(SDKのインストールなど)をAndroid Studio上で行った上でご利用ください。

# 会員管理について
## 認証の種類
* 会員の認証方法は4つあります。
 * ユーザー名とパスワードによる認証
 * メールアドレスとパスワードによる認証
 * 匿名認証
 * SNSアカウント（Facebook/Twitter/Google）での認証
* ここでは上３つを扱います。
* 「SNSアカウントでの認証」については下記__＜SNS連携編＞__をご覧ください。
 *  KotlinでFacebook連携しよう！　※準備中
 *  KotlinでTwitter連携しよう！　※準備中
 *  KotlinでGoogle連携しよう！　※準備中

## ダッシュボードでの事前設定
ここで扱う３つの認証方法

 * ユーザー名とパスワードによる認証
 * メールアドレスとパスワードによる認証
 * 匿名認証

は、いずれにおいても__認証を許可する設定__を、[ニフクラ mobile backend ](http://mbaas.nifcloud.com/)のダッシュボード上で行わなければなりません。

[ニフクラ mobile backend ](http://mbaas.nifcloud.com/)にログインして、ブラウザでダッシュボードを開いてください。

* ユーザー名とパスワードによる認証とメールアドレスとパスワードによる認証は _アプリ設定_＞_会員認証設定_ に設定項目があります。
* 匿名認証は _アプリ設定_＞_基本_ の画面の下のほうに設定項目があります。
![ProjectSettings.png](https://qiita-image-store.s3.amazonaws.com/0/72656/525618b7-b653-47b8-4ec6-c1ee11c9ce70.png)



* コードを実行する前に「__許可する__」に設定をして「__保存する__」ボタンで必ず保存をしおいてください。

# __Kotlinでログイン機能をつけてみよう！__
* [ニフクラ mobile backend ](http://mbaas.nifcloud.com/)のダッシュボードで確認をしながらAndroid Studioで動作確認をしてください。
* ドキュメントの動作確認の方法については[Kotlinでデータベースを使おう！①（保存・取得・更新・削除）](https://qiita.com/nifcloud_mb/items/eef8102fd47bf7e5aa9f)の「ドキュメントの動作確認方法」にまとめてありますので参考にしてみてください◎

## __ユーザー名・パスワード認証__
### ユーザーの新規登録
NCMBUserオブジェクト作成後、signUpInBackgroundメソッドで登録処理を行います

```kotlin:Kotlin
//NCMBUserのインスタンスを作成
val user = NCMBUser()
//ユーザー名を設定
user.setUserName("user1")
//パスワードを設定
user.setPassword("password1")
//会員の登録を行う
user.signUpInBackground { e ->
    if (e != null) {
        // 新規登録失敗時の処理
    } else {
        // 新規登録成功時の処理
    }
}
```

### ログイン
loginInBackgroundメソッドに新規登録時に設定したユーザ名とパスワードを指定してログインします

```kotlin:Kotlin
try {
    // ユーザー名とパスワードでログイン
    NCMBUser.loginInBackground("user1", "password1") { ncmbUser, e ->
        if (e != null) {
            // ログイン失敗時の処理
        } else {
            // ログイン成功時の処理
        }
    }
} catch (e: NCMBException) {
    e.printStackTrace()
}
```

* ログインをすると「セッショントークン」というものが発行されます。これによって特定のユーザーの権限でオブジェクトにアクセスできるようになります。

### ログアウト
logoutメソッドを利用します。

```kotlin:Kotlin
// ログアウト
try {
    NCMBUser.logout()
} catch (e: NCMBException) {
    e.printStackTrace()
}
```

* ログアウトすることでセッショントークンは無効になります。
* セッショントークンはログアウトしなくてもデフォルトで24時間たつと無効になります。有効期限の変更は先程のダッシュボードで行えます。

### ログイン中のユーザーの取得
getCurrentUserメソッドで、現在ログイン中のユーザー（カレントユーザー）情報を取得することができます。

```kotlin:Kotlin
val currentUser = NCMBUser.getCurrentUser()
```

## __メールアドレス・パスワード認証__
メールアドレス認証は、

1. 利用者がメールアドレスを入力して認証をリクエストする
2. 入力したメールアドレスに対して会員登録画面へのURLを含むメールが送信される
3. メールから会員登録画面を開き、パスワードを入力して会員登録を行う
4. メールアドレスとパスワードでのログインが可能になる

という流れになっています。
※ 2.の送信元メールアドレスや、メール本文の内容は先程のダッシュボードで設定ができます。

### 会員登録用のメールを要求する
requestAuthenticationMailメソッドを実行すると、メールアドレスでの会員登録を行うためのメールが送信されます。

```kotlin:Kotlin
try {
    NCMBUser.requestAuthenticationMail("test@nifty.com")
} catch (e: NCMBException) {
    e.printStackTrace()
}
```

* `"test@nifty.com"`の部分をお持ちのメールアドレスに書き換えて試してみてください！

### ログイン
loginWithMailAddressInBackgroundメソッドに、登録時に設定したメールアドレスとパスワードを指定してログインします。

```kotlin:Kotlin
// メールアドレスとパスワードでログイン
NCMBUser.loginWithMailAddressInBackground("test@nifty.com", "password2") { ncmbUser, e ->
    if (e != null) {
        // ログイン失敗時の処理
    } else {
        // ログイン成功時の処理
    }
}
```
* __ログアウト__はユーザー名・パスワード認証と同様です。

## __匿名認証__
ユーザー名・パスワードを入力せずに会員登録をすることができます。ただし、一度ログアウトをすると、次にログインする場合は別のユーザーとして登録されてしまうので、仮ユーザーとして利用する用途で使います。

### ログイン
loginWithAnonymousInBackgroundメソッドを利用して、匿名ユーザーでログインします。

```kotlin:Kotlin
// 匿名ユーザーでログイン
NCMBUser.loginWithAnonymousInBackground { ncmbUser, e ->
    if (e != null) {
        // ログイン失敗時の処理
    } else {
        // ログイン成功時の処理
    }
}
```
### ログイン中の匿名ユーザーの取得
isLinkedWithメソッドで匿名ユーザーでログインしているか確認できます。

```kotlin:Kotlin
if(NCMBUser.getCurrentUser().isLinkedWith("anonymous")) {
    // 匿名ユーザーでログインしている時の処理
}else{
    // 匿名ユーザーでログインしていない時の処理
}
```

## __会員のグルーピング（ロール）__
ロールは、会員をグルーピングするための機能です。

### ロールの作成
NCMBRoleクラスを利用します。

```kotlin:Kotlin
// ロールの作成
val basicPlanRole = NCMBRole("basicPlan")
basicPlanRole.createRoleInBackground { }
val expertPlanRole = NCMBRole("expertPlan")
expertPlanRole.createRoleInBackground { }
```

### 会員をロールに追加する
addUserInBackgroundメソッドを利用します。

```kotlin:Kotlin
// ロールに追加するユーザーを作成
val user = NCMBUser()
user.setUserName("basicPlanUser")
user.setPassword("password")
user.signUpInBackground { e ->
    if (e != null) {
        // ユーザー作成失敗時の処理
    } else {
        // ユーザー作成成功時の処理
        // 既存ロールの"basicPlan"を検索
        val query = NCMBRole.getQuery()
        query.whereEqualTo("roleName", "basicPlan")
        query.findInBackground { list, e2 ->
            if (e2 != null) {
                // 検索失敗時の処理
            } else {
                if (list.size > 0) {
                    // 検索成功時の処理
                    // 検索結果をロールに設定してユーザーを追加
                    val role = list[0]
                    role.addUserInBackground(Arrays.asList(user)) { e3 ->
                        if (e3 != null) {
                            // ユーザー追加失敗時の処理
                        } else {
                            // ユーザー追加成功時の処理
                        }
                    }
                }
            }
        }
    }
}
```
### 子ロールの追加
* ロールの中にロールを作成します。

親ロールの中に子ロールを作成するには、addRoleInBackgroundメソッドを利用します。

```kotlin:Kotlin
// 子ロール
val childRole = NCMBRole("childRole")
childRole.createRole()
val role = NCMBRole("Role")
role.createRole()
role.addRoleInBackground(Arrays.asList(childRole)) { e ->
    if (e != null) {
        // ユーザー追加失敗時の処理
    } else {
        // ユーザー追加成功時の処理
    }
}
```