📝

Flutter × FirebaseAuth 自作APIの認証について

2021/11/26に公開

現在Flutterアプリを開発中です。自前のサーバーを立ててAPIを作成するということが良くあると思います。その中でAPIに正規のユーザーしか受け付けないように認証を実装します。FirebaseでFlutterアプリの認証を行なっているのでAPIの認証もFirebaseに任せたいと思います。今回の構成図は以下の通りです。

jwt.png

JWTとは

Json Web Tokenの略で読み方はジョット。JSONデータ構造で表現したトークンの仕様です。
JWTは長い文字列になっていますが . によって3つに分割することができます。構成は<ヘッダー>.<ペイロード>.<署名>となってます。JWT実際にデコードしていってみます。色々検証してみたい方はこちら↓↓↓

https://jwt.io/

ヘッダー

ヘッダーはJWTの署名検証を行うために必要な情報を格納しています。"typ"はJWTであることを示し、"alg"は署名アルゴリズムを示しています。公開鍵方式であり署名の作成に秘密鍵を利用。署名の検証に 公開鍵を利用。"kid"は鍵IDとなっています。

{
  "alg": "RS256",
  "kid": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "typ": "JWT"
}

ペイロード

ペイロードはやりとりに必要な属性情報(Claim)です。送信したい情報を格納しています。


{
  "provider_id": "anonymous",
  "iss": "https://securetoken.google.com/xxxxxxxxxxxxx",
  "aud": "xxxxxxxxxxxxxxxxxxx",
  "auth_time": 1234567890,
  "user_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "sub": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "iat": 1234567890,
  "exp": 1234567890,
  "firebase": {
    "identities": {},
    "sign_in_provider": "anonymous"
  }
}

署名

署名は、<エンコードしたヘッダー>.<エンコードしたペイロード>を連結したものを入力値として"alg"の署名アルゴリズムで署名し、Base64urlエンコードすることにより作成されます。これをJWTで送られてきた署名と比較して一致すれば認証成功になります。

実践編

Firebase Admin SDKを導入する

サーバーサイド側(Node.js)にFirebase Admin SDKを導入します。メリットとしては比較的シンプルなコードでJWTを検証することができます。Firebaseでサポートされていない言語の場合でもサードパーティのJWTライブラリを使用して検証することもできます。

https://firebase.google.com/docs/admin/setup?hl=ja

JWTを取得する

クライアント側で(Flutter)でJWTを取得します。

公式に以下のような記述があります↓↓↓
Firebase Authentication セッションは長期間有効です。ユーザーがログインするたびに、ユーザー認証情報が Firebase Authentication のバックエンドに送信され、Firebase ID トークン(JWT)および更新トークンと交換されます。Firebase ID トークンの有効期間は短く、1 時間で期限切れとなります。

String idToken = await FirebaseAuth.instance.currentUser!.getIdToken();

JWTを付与してリクエストを行う

クライアントがJWTをヘッダーに含めて送信します。

Authorization: Bearer <JWT>

JWTを検証する

サーバーサイド側(Node.js)でJWTの検証はFirebase Admin SDKによって簡単にできます。Firebaseが送信したidTokenか改ざんされていないidTokenかを検証します。

admin.auth().verifyIdToken(idToken).then((decodedToken) => {
    // 認証成功
    const uid = decodedToken.uid;
}).catch((error) => {
    // 認証失敗
});

参考文献

・JWTについて

https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be

https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/

https://deecode.net/?p=1544#JWTトークン検証の仕組み

・Firebase公式

https://firebase.google.com/docs/admin/setup?hl=ja

https://firebase.google.com/docs/auth/admin/create-custom-tokens?hl=ja

https://firebase.google.com/docs/auth/admin/verify-id-tokens?hl=ja#node.js

・その他参考

https://qiita.com/masatomix/items/b446a07a641f97686a97#自前restサーバの構築

https://zenn.dev/awakei/articles/775c030922bf9c6ab56e

Discussion