概要
Firebase Authenticationに登録されているどのアカウントか判断し、なにか処理をおこなうAPIを**API Gateway(AWS)とlambda(AWS)**を利用して作成します。
※せっかくなのでlambda(AWS)では新機能のレイヤーの使い方も説明しちゃおうと思います。
対象者
Firebase Authenticationの機能を知っている人
Firebase Authenticationを利用したAPIを作成したい人
Firebase Admin SDKについて
自作APIでアカウントの判断をするためには、firebase
ではなくfirebase-admin
が必要になります。
firebases-admin
では、アカウントが発行するトークンをもとに、どのアカウントか判断できる機能があります。この機能を利用することで自作APIを作成していきます。
Firebaseプロジェクトの作成
Firebase consoleを開き、新規プロジェクトを作成します。
開発のAuthenticationを開き、Googleを有効にします。
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2Fc2093f55-62cd-9584-badc-e709eee07f9b.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=4a00876e9b0f4431b03da86e3b0c1ed3)
プロジェクトの設定のサービスアカウント画面を開きます。
Project Overviewの右の馬車アイコンから、プロジェクトの設定を選択し、サービスアカウントを開きましょう。
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2F681da740-9633-e0c0-116f-dfc0b0e6b834.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=f802d30ef2a2d0dbc51c91424b332141)
Firebase Admin SDKの新しい秘密鍵の生成からjsonファイルをダウンロードしましょう。databaseURLの値は後で使うのでメモしておきます。
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2F9d098855-93c0-4340-e1d9-76da85fb9aeb.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=c3f17a79bd986c2ce211edb27ca88a46)
firebase consoleですることは終わりです。
APIの作成
イメージ
firebase-sdkはTokenの発行、
firebase-admin-sdkはTokenをチェックします。
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2F3d9f1cf4-901e-8015-035a-c84f5145f29d.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=79066534062d2a2b957a3104819327ff)
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](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2Fe0e56abd-9a5a-a735-1c0d-17161a2b0b37.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=6a60704ea51e42dc5f83ef63e28d775d)
次に、Lambda関数本体を書いていきます。
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](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2Ffcf8a082-9216-6ef9-37ea-33f97db6a4d6.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=341b4613d0540145cd2073fdaf494bc2)
firebase-admin
のauth
のverifyIdToken
関数で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](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2Fd53e2915-36c8-31db-b084-b48a64b51d5d.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=07b03d2f5b912a28b8f64b4788786f25)
はじめに、FirebaseのTokenを送信するカスタムヘッダーを設定します。
メソッドリクエストを選択し、HTTPリクエストヘッダーにX-FIREBASE-TOKENを追加、リクエストの検証を「クエリ文字列パラメータおよびヘッダーの検証」に変更します。
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2F178d25c4-b50f-4558-fb7a-3affec7aec1e.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=fbd8b4daf015bae904601af048fc1579)
次に、ヘッダーのX-FIREBASE-TOKENをLambda関数で受け取れるように設定します。
統合リクエストを選択し、マッピングテンプレートのリクエスト本文のパススルーを「テンプレートが定義されていない場合」に変更します。
application/jsonでマッピングテンプレートを追加します。
Lambda関数内でevent.token
でX-FIREBASE-TOKENの値を取得できるようになります。
{
"token": "$input.params('X-FIREBASE-TOKEN')"
}
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2F80843fa0-ce3d-03db-44c7-5192034c0ede.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=e1e21b051edda30bae670d19054b8ae9)
リソースでアクション→APIのデプロイより、ステージを新しく作成しAPIを完成させましょう。
![キャプチャ.JPG](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2Ff51f2d07-1fed-167b-f2ea-cb5d4dc9dfb9.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=615b071cebf7d9859571d899bbc7b346)
APIの作成は完了です。
APIの利用
クライエントサイドは情報が溢れているため端折らせてもらいます。
※React Firebase SNS認証等で調べればたくさん出てきます。
firebase
とaxios
をインストールします。
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](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F189146%2F9c3f3dbf-b033-08db-e8bf-fa97111535f5.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=78437bdcad7aa64da642c57ed6b478b4)
configファイルを作成します。
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アプリでもサクッと作って試してみましょう。
最後に
firebaseのSNS認証機能はかなり強力で、爆速でアプリ開発できます。
ただアプリ開発おいて、DBは自前でもちたい等、firebaseのサービスだけで完結できるとは限らないです。
そのため、今回はfirebaseのサービス以外と連携させるためのAPIの作成方法を紹介させていただきました。