Firebaseのカスタム認証を利用する


特定の文字列（UID）を送ると、その文字列（UID）に紐付いたTokenを返してきてくれるしくみ。
これを利用することで、既存の認証の仕組みとFirebaseのAuthenticationを連携させるととができる。

## 想定例

別に、既存の認証のためにある機能ではなく、あくまでカスタムTokenの発行・認証機能であえるが、下記のような利用もできるってことかな。

* 現在、独自DBでuserとpasswordを管理
* 独自dbのuser名（一意）をFirebaseに送りTokenを発行
* Tokenを独自dbに保存（これでいいのか？）
* Firebase関連のサービスを利用する際、そのTokenで認証し、サービスを利用する

というような感じか？


## やってみる

### tokenの発行（サーバ側）

adminである必要があるので、実際はfunctions等で行うのだろうが、一旦、ローカルのnodeプログラムで書いてみる。
秘密鍵ファイルは各自の環境に合わせる。

```js:getToken.js
const admin = require('firebase-admin');
const serviceAccount = require('/path/to/key.json');
const firebase = require('firebase');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://project-id.firebaseio.com',
});

const db = admin.firestore();

admin.auth().createCustomToken('hogehoge')
    .then(token => {
        console.log(token);
    })
    .catch(e => {
        console.log(e);
    });

```

上記を実行すると、

```
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL2lkZW50aXR5dG9vbGtpdC5nb29nbGVhcGlzLmNvbS9nb29nbGUuaWRlbnRpdHkuaWRlbnRpdHl0b29sa2l0LnYxLklkZW50aXR5VG9vbGtpdCIsImlhdCI6MTU3NDY3NzI3NSwiZXhwIjoxNTc0NjgwODc1LCJpc3MiOiJmaXJlYmFzZS1hZG1pbnNkay15NTl2YkB0YW1hLXRlc3QtYjc0ODguaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzdWIiOiJmaXJlYmFzZS1hZG1pbnNkay15NTl2YkB0YW1hLXRlc3QtYjc0ODguaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJ1aWQiOiJob2dlaG9nZSJ9.p7F00RKB8FPSOR7oxfoUk1keoQeDLjDrAQ9vXbA0MggN_Z8d5AJGmsMH-47GQqiadiCQUObFzIgF_1tI3r7b4UHeZsV1ZAIM-0Nh7fgd6UMSLB7-JeLUNM35Aqg39qYM-GrnmCMFGEZ946zbOSP3SeNCLZdh_m9rLdKH5S8DR55WKjVHj9SwGa_7t4GyQNM7CSgqplJWk82P1kLbdJ51wZQkR5XT4tSgCbxCh3gdFEhHF2qnrtHhSgUa4E7105htCj2Cm_gaB3VBKGEPsB-sRzjtADEX2JTUdgns7DO6__XAXe49XUIyrkJy1pJl05TSGMPnMTD0to9wghP3gABCD
```

のようなレスポンスがある。これをメモしておく。


### tokenの利用（クライアント側）

firebaseConfigの情報は各自の環境に合わせる。

```js:authUser.js
const firebase = require('firebase');

const firebaseConfig = {
    apiKey: "xxxxxxxxxx",
    authDomain: "xxxxxxxxxxx",
    databaseURL: "xxxxxxxxxxxxxx",
    projectId: "xxxxxxxxxxxxx",
    storageBucket: "xxxxxxxxxxxx",
    messagingSenderId: "xxxxxxxxx",
    appId: "xxxxxxxxxxxxxxxxxxxxxxxx"
  };

firebase.initializeApp(firebaseConfig);

const token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL2lkZW50aXR5dG9vbGtpdC5nb29nbGVhcGlzLmNvbS9nb29nbGUuaWRlbnRpdHkuaWRlbnRpdHl0b29sa2l0LnYxLklkZW50aXR5VG9vbGtpdCIsImlhdCI6MTU3NDY3NzI3NSwiZXhwIjoxNTc0NjgwODc1LCJpc3MiOiJmaXJlYmFzZS1hZG1pbnNkay15NTl2YkB0YW1hLXRlc3QtYjc0ODguaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzdWIiOiJmaXJlYmFzZS1hZG1pbnNkay15NTl2YkB0YW1hLXRlc3QtYjc0ODguaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJ1aWQiOiJob2dlaG9nZSJ9.p7F00RKB8FPSOR7oxfoUk1keoQeDLjDrAQ9vXbA0MggN_Z8d5AJGmsMH-47GQqiadiCQUObFzIgF_1tI3r7b4UHeZsV1ZAIM-0Nh7fgd6UMSLB7-JeLUNM35Aqg39qYM-GrnmCMFGEZ946zbOSP3SeNCLZdh_m9rLdKH5S8DR55WKjVHj9SwGa_7t4GyQNM7CSgqplJWk82P1kLbdJ51wZQkR5XT4tSgCbxCh3gdFEhHF2qnrtHhSgUa4E7105htCj2Cm_gaB3VBKGEPsB-sRzjtADEX2JTUdgns7DO6__XAXe49XUIyrkJy1pJl05TSGMPnMTD0to9wghP3ABCDE";

firebase.auth().signInWithCustomToken(token)
    .then(res => {
        console.log(res.user.uid); //hogehogeが帰るはず。
        //res.user.updateEmail("hoge@hoge.com"); emailを保存したりもできる。
    })
    .catch(e => {
        console.log(e);
    })
```

こを実行すると、

```bash
hogehoge
```

と表示されるはず。
後はこれを応用するだけ。

管理画面でみると、下記のように追加されている。

>下記画面はemailをupdateして追加した状態。

![スクリーンショット 2019-11-25 19.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/961e3192-7c25-f070-dead-73312ef59045.png "スクリーンショット 2019-11-25 19.33.38.png")

customTokenで追加したユーザーにemail, tel等を追加し、認証（実在確認等）が行えるかそのうち試してみたい。