Firebase Authenticationとは、「Googleに認証」などの外部サイトのログイン情報で良い感じに認証できる機能を、簡単に実装できるサービスです。
今回はこれのサーバ側、つまり「クライアント側から渡されたトークンを検証する」機能の実装を行いたいと思います。ちなみに自分はFlutterでクライアント側を実装しています。
SDK導入
まずはSDKの導入。
npm install firebase-admin
次に設定ファイルをfirebaseのsettings->サービスアカウントからダウンロード。アプリケーションのルートに配置しました。
また、この時スニペットに書いてあるdatabaseURLも控えておきましょう。
そしてenvファイルに以下の値を追加。nodeで.envを使える様にするにはこちらを参照。
GOOGLE_APPLICATION_CREDENTIALS=jsonファイルまでのフルパス.json
GOOGLE_APPLICATION_DATABASE=先ほど控えたdatabaseURL
GOOGLE_APPLICATION_CREDENTIALに関してはadminSDKが使うものです。下は後で使います。
その後、まずは初期化コードを実装。私はapp.jsに実装しました。
var admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: process.env.GOOGLE_APPLICATION_DATABASE
});
というのも初期化処理が複数回走るとエラーが出てしまうので、APIサーバ立てるならapp.jsで初期化するのが無難なのかなって感じです。
ここまででSDKの導入処理は完了です。
HTTPメソッド側変更
まず、SDKを使うためには各HTTPメソッドをasync,awaitに対応させる必要があります。
私は以下を基本形にしています。
router.get('/test', (req, res, next) => {
(async () => {
//色々処理してres.status().send();
})().catch(next);
});
こうすると、firebase admin SDKの非同期な処理をawaitして良い感じに処理することができます。
実際にfirebaseにトークンを投げて認証結果を返してもらう処理がこちら。
var admin = require('firebase-admin');
async function verifyToken(token) {
await admin.auth().verifyIdToken(token)
.then(function (decodedToken) {
return decodedToken.uid;
}).catch(function (error) {
console.log(error);
return '';
});
}
また、リクエストからBearerトークンを取り出す処理はこちら。
function getBearerToken(req) {
let token = '';
if (req.headers.authorization &&
req.headers.authorization.split(' ')[0] === 'Bearer') {
token = req.headers.authorization.split(' ')[1];
}
return token;
}
Bearer認証を使うと、「Bearer ◯◯◯~~」という風に、クライアントで設定した情報が渡されるので、それを分解しています。
まとめ
いろんな概念や考え方が出てきましたが、理解してしまえば問題なく実装できるレベルだと思います。
この認証が出来る・出来ないでかなり全体設計も変わってくると思うので、是非試していただければと思います。