【Firebase】自作API(API Gateway + Lambda)でFirebaseのAuthorizationを利用する方法

【Firebase】自作API(API Gateway + Lambda)でFirebaseのAuthorizationを利用する方法:


概要

Firebase Authorizationに登録されているどのアカウントか判断し、なにか処理をおこなうAPIをAPI Gateway(AWS)lambda(AWS)を利用して作成します。

せっかくなのでlambda(AWS)では新機能のレイヤーの使い方も説明しちゃおうと思います。


対象者

Firebase Authorizationの機能を知っている人

Firebase Authorizationを利用したAPIを作成したい人


Firebase Admin SDKについて

自作APIでアカウントの判断をするためには、firebaseではなくfirebase-adminが必要になります。
firebases-adminでは、アカウントが発行するトークンをもとに、どのアカウントか判断できる機能があります。この機能を利用することで自作APIを作成していきます。


Firebaseプロジェクトの作成

Firebase consoleを開き、新規プロジェクトを作成します。

開発のAuthenticationを開き、Googleを有効にします。



キャプチャ.JPG


プロジェクトの設定のサービスアカウント画面を開きます。

Project Overviewの右の馬車アイコンから、プロジェクトの設定を選択し、サービスアカウントを開きましょう。



キャプチャ.JPG


Firebase Admin SDKの新しい秘密鍵の生成からjsonファイルをダウンロードしましょう。databaseURLの値は後で使うのでメモしておきます。



キャプチャ.JPG


firebase consoleですることは終わりです。


APIの作成


イメージ

firebase-sdkTokenの発行、
firebase-admin-sdkTokenをチェックします。



キャプチャ.JPG



API環境の準備(AWS)

ローカル環境にAPIを作るのもいいのですが、最終的にはAWSを利用したり、Azureを利用してAPIを公開していくものだと思っているので、いきなりAWS上に環境作ります。


Layerの作成

今回はfirebase-adminを使用します。
firebase-adminをLambdaで利用できるようにするため、Layerを作成してみましょう。Layerはソースコードの共有が可能になる機能です。Lambda関数内でLayerを読み込むことでfirebase-adminが即座に利用可能になります。

PC上にnodejsという名前でフォルダを作成し、フォルダ内でfirebase-adminをインストールします。

※Layerは読み込むファイルのパスが決まっているため、フォルダ構成はnodejs/node_modules/にしなければなりません。ほかの構成でも読み込めますが詳しくはこちらをご覧ください。

library version
firebase-admin v6.3.0
npm install firebase-admin 
AWSマネジメントコンソール画面でLambdaのLayersを選択し、

新規Layerをランタイム Node.js 8.10で、先ほど作成したnodejsフォルダをzip化してS3経由でアップロードし、作成します。

※S3経由でのアプロード方法がわからない方はGoogleで調べてください。


Lambda関数の作成

AWSマネジメントコンソール画面でLambdaの関数を選択し、

新規関数をランタイム Node.js 8.10で作成します。

Layersを選択し、レイヤーの追加から先ほど作成したLayerを追加します。



キャプチャ.png


次に、Lambda関数本体を書いていきます。

index.js
const admin = require('firebase-admin'); 
const firebaseDatabaseEndpoint = process.env.FIREBASE_DATABASE_ENDPOINT; 
 
const serviceAccount = require('./admin.json'); 
 
admin.initializeApp({ 
    credential: admin.credential.cert(serviceAccount), 
    databaseURL: firebaseDatabaseEndpoint, 
}) 
 
exports.handler = async (event, context, callback) => { 
    // firebase uid 検証 
    const uid = await admin.auth().verifyIdToken(event.token) 
        .then((decodedToken) => { 
            return decodedToken.uid; 
        }) 
        .catch((error) => { 
            console.log(error); 
            return null; 
        }) 
 
    if(uid) { 
        // 検証に成功している場合実行する処理 
        console.log('hello firebase'); 
 
        const response = { 
            statusCode: 200, 
            body: {  
                message: 'verify token success.', 
                uid: uid 
            }, 
        }; 
 
        return response; 
    } 
    else { 
        const response = { 
            statusCode: 500, 
            body: { 
                message: 'verify token failure.' 
            }, 
        }; 
 
        return response; 
    } 
}; 
firebaseのプロジェクトの設定をします。

firebaseDatabaseEndpointには、さきほどメモしておいたdatabaseURLを環境変数で設定します。serviceAccountには、さきほどダウンロードした秘密鍵をadmin.jsonとしてアップロードし読み込みます。

const admin = require('firebase-admin'); 
const firebaseDatabaseEndpoint = process.env.FIREBASE_DATABASE_ENDPOINT; 
 
const serviceAccount = require('./admin.json'); 
 
admin.initializeApp({ 
    credential: admin.credential.cert(serviceAccount), 
    databaseURL: firebaseDatabaseEndpoint, 
}) 
 
キャプチャ.JPG

firebase-adminauthverifyIdToken関数でTokenの検証を行います。検証に成功した場合は、アカウント毎に設定されているuidを獲得できます。

// firebase uid 検証 
const uid = await admin.auth().verifyIdToken(event.token) 
    .then((decodedToken) => { 
        return decodedToken.uid; 
    }) 
    .catch((error) => { 
        console.log(error); 
        return null; 
    }) 
 
次に、uidの有無で処理を分けて、最後にレスポンスを返すようにします。

if(uid) { 
    // 検証に成功している場合実行する処理 
    console.log('hello firebase'); 
 
    const response = { 
        statusCode: 200, 
        body: {  
            message: 'verify token success.', 
            uid: uid 
        }, 
    }; 
 
    return response; 
} 
else { 
    const response = { 
        statusCode: 500, 
        body: { 
            message: 'verify token failure.' 
        }, 
    }; 
 
    return response; 
} 
これでLambdaは完成です。


API Gatewayの作成

AWSマネジメントコンソール画面でAPI Gatewayの新規APIを作成します。作成したAPIのリソースでアクション→メソッドの作成よりGETを追加します。

統合タイプはLambda 関数で、Lambda関数の欄は先ほど作成した関数を入力します。



キャプチャ.JPG


はじめに、FirebaseのTokenを送信するカスタムヘッダーを設定します。

メソッドリクエストを選択し、HTTPリクエストヘッダーにX-FIREBASE-TOKENを追加、リクエストの検証を「クエリ文字列パラメータおよびヘッダーの検証」に変更します。



キャプチャ.JPG


次に、ヘッダーのX-FIREBASE-TOKENをLambda関数で受け取れるように設定します。

統合リクエストを選択し、マッピングテンプレートのリクエスト本文のパススルーを「テンプレートが定義されていない場合」に変更します。
application/jsonでマッピングテンプレートを追加します。

Lambda関数内でevent.tokenX-FIREBASE-TOKENの値を取得できるようになります。

application/json
{ 
    "token": "$input.params('X-FIREBASE-TOKEN')" 
} 


キャプチャ.JPG


リソースでアクション→APIのデプロイより、ステージを新しく作成しAPIを完成させましょう。



キャプチャ.JPG


APIの作成は完了です。


APIの利用

クライエントサイドは情報が溢れているため端折らせてもらいます。

React Firebase SNS認証等で調べればたくさん出てきます。

firebaseaxiosをインストールします。

npm install firebase 
npm install axios 
library    version
firebase v5.7.0
axios v0.18.0


configファイルの準備

Firebase consoleを開き、プロジェクトを開きます。

開発のAuthenticationを開き、ウェブ設定を押して、configを確認します。



スクリーンショット 2018-12-15 1.31.13.png


configファイルを作成します。

config.js
export const config = { 
    apiKey: "xxxx", 
    authDomain: "xxxx", 
    databaseURL: "xxxx", 
    projectId: "xxxx", 
    storageBucket: "xxxx", 
    messagingSenderId: "xxxx" 
  }; 


ログインの例

GoogleとFacebookのログインの仕方を書いています。

import * as firebase from 'firebase' 
import { config } from './config' // config読み込み 
firebase.initializeApp(config) 
 
const googleProvider = new firebase.auth.GoogleAuthProvider() 
const facebookProvider = new firebase.auth.FacebookAuthProvider() 
 
const auth = firebase.auth() 
 
// Google Login 
const authGoogle = () => { 
    auth.signInWithRedirect(googleProvider) 
} 
 
// Facebook Login 
const authFacebook = () => { 
    auth.signInWithRedirect(facebookProvider) 
} 
 


Token取得の例

ログイン時のアカウントのTokenの取得方法を書いています。

import * as firebase from 'firebase' 
import { config } from './config' // config読み込み 
firebase.initializeApp(config) 
 
const auth = firebase.auth() 
 
auth.currentUser.getIdToken(true).then((idToken) => { 
    const token = idToken 
    console.log(token) 
}) 
.catch(err => { 
    console.log(err) 
}) 
 


リクエスト送信の例

X-FIREBASE-TOKENに先ほど取得した、Tokenを設置し、GETリクエストを送信します。

import axios from 'axios' 
 
const lambdaEndpoint = 'xxxx' 
const token = 'xxxx' 
 
axios.get(lambdaEndpoint, {} ,{ 
    headers: { 
        'X-FIREBASE-TOKEN': token 
    } 
}) 
.then(res => { 
    console.log(res.data) 
}) 
.catch(err => { 
    console.log(err) 
}) 
 
これらのコードを利用して、Reactアプリでもサクッと作って試してみましょう。

※_これらのコードを利用したReactアプリのサンプルは12月中にgithubにて公開し、ここにリンク貼ります。


最後に

firebaseのSNS認証機能はかなり強力で、爆速でアプリ開発できます。

ただアプリ開発おいて、DBは自前でもちたい等、firebaseのサービスだけで完結できるとは限らないです。

そのため、今回はfirebaseのサービス以外と連携させるためのAPIの作成方法を紹介させていただきました。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)