Firebase 3でトークンのサーバー側の検証を行うことはまだ可能ですか?
既存の認証システムを使用して(サービスアカウントを使用して)Golangを実行しているサーバーでカスタムトークン(JWT)を生成します。トークンは、次を使用してiOSクライアントで使用されます
FIRAuth.auth()?.signInWithCustomToken(customToken)
それまではすべて正常に動作します。ただし、次の場所から取得したサーバーにクライアントトークンを渡すと、
FIRUser.getTokenWithCompletion({ token, error in ..})
確認できません。 JWTトークンはRS256を使用して署名されており、認識できないheader.kidがあります。サービスアカウント(カスタムトークンの署名に使用された)からの公開キーは、クライアントトークンを検証しません。クライアントトークンを検証するために公開キーが必要ですか?
JavaまたはJavascriptの "verifyIdToken"呼び出しを使用してクライアントトークンを検証することは可能ですが、標準のJWTライブラリを使用してGolangでこれを実行できるようにしたいと考えています。
これはすべてFirebase 2で正常に機能しました(HS256とFirebaseシークレットを使用)。
簡単な答えはイエスです。完全な答えは、ほとんどの場合、現在、より適切なツールがあることです。そのため、解決しようとしているユースケースに大きく依存します。
新しいSDKバージョンはかなり強力であり、機能を要約するのに優れた仕事をしていません。これは、利用可能なツールとその使用法を対比するのに適した場所のように思えます。最後に、サードパーティ(つまりGo)固有の注意事項について説明します。
クライアント認証に外部認証ツールを使用する
カスタムトークンのミントの主な用途は、LDAPサーバーなど、ユーザーが制御する外部/レガシー認証メカニズムに対してユーザーが認証できるようにすることです。この基本的なプロセスについては、 iOS 、 Android 、 Web をご覧ください。
基本的に、サービスはJWTトークンを作成し、これをクライアントに渡します。クライアントは、指定されたカスタムトークンを使用して検証/認証を行います。
特権ワーカーの認証
サーバープロセスの認証にカスタムトークンを使用する必要はなくなりました。これは、 Firebaseをサーバーに追加する で段階的に説明されているサービスアカウントを作成することによって行われます。完了すると、秘密鍵を含むJSONファイルが作成されます。
次に、firebase.initializeApp()
のserviceAccount
属性を使用してそのJSONを参照することにより、サービスアカウントの資格情報を含めます。それは here で文書化されており、このように見えます(Java version)のリンクを参照してください):
_var firebase = require("firebase");
// Initialize the app with a service account, granting admin privileges
firebase.initializeApp({
databaseURL: "https://databaseName.firebaseio.com",
serviceAccount: "./serviceAccountCredentials.json"
});
_
ユーザーのエミュレーションまたはサーバープロセスからのアクセスの制限
ユーザーをエミュレートしたり、サーバープロセスからのアクセスを制限したり(非常に推奨)するのはかなり簡単です。本当にこれのためにカスタムトークンを作成する必要はありません。
これには、databaseAuthVariableOverride
をdatabase.initializeApp()
への呼び出しに追加するだけです。
_firebase.initializeApp({
databaseURL: "https://databaseName.firebaseio.com",
serviceAccount: "./serviceAccountCredentials.json",
databaseAuthVariableOverride: {
uid: "my-service-worker-or-user-uid"
}
});
_
セキュリティを介したクライアントIDの検証
まず、クライアントにデータベースへの書き込みを許可し、セキュリティルールを使用してIDを検証することにより、Firebase Databaseを使用している場合、通常はサーバー側の検証を回避できます。サーバーが書き込みに認証を必要とするパスでリッスンする場合、これはサーバーで特別なセキュリティなしで既に解決されています。
これをイベントキューとしてモデル化することにより、シンプルでモジュール式のスケーラブルなサーバーワーカー戦略を作成します。 Node.jsの優れたツールについては、 firebase-queue をご覧ください。それ .xをサポート 。
サーバー上のクライアントIDトークンの検証
Realtime Databaseを使用しておらず、クライアントトークンを受信する必要がある場合(たとえばREST呼び出し)で、それらが有効であることを確認する場合は、verifyIdToken()
説明どおり here これは次のようになります。
_auth.verifyIdToken(idToken).then(function(decodedToken) {
var uid = decodedToken.sub;
});
_
その後、そのユーザーとして認証してデータベースに書き込み、セキュリティを強化する場合は、上記のEmulating Usersセクションを使用します。つまり、databaseAuthVariableOverride
を適切なuidに設定してinitializeApp()
を呼び出します。
initializeApp()
を複数回呼び出して、次のようなエラーに遭遇した場合:_Error: Firebase App named '[DEFAULT]' already exists.
_ initializeApp()呼び出しに2番目の引数を追加することにより、複数のアプリコンテキストを初期化できます。例:database.initializeApp({...}, 'asUser'+uid)
)そして、firebase.database('asUser'+uid)
。ref(...)を使用してそのアプリインスタンスを参照します。複数のアプリインスタンスの使用について詳しくは、 こちらをご覧ください をご覧ください。
上記のリンクで利用可能なJavaコード。 Goおよびその他のサードパーティのソリューションは、以下で説明します。
REST APIで使用するためのトークンの作成
Michael Bleighがこのシナリオを取り上げました here 、これを解決するためのいくつかの代表に値します。
RESTを介したトークンの作成または検証
これはサポートされていません。ごめんなさい。
Golangとその他:今後追加予定
Goトークンのマイニングおよび検証ライブラリに取り組んでいます。また、このためにPythonツールも追加します。このリリース日や球場はありません。当面は、公式を使用せずにクライアントIDトークンを確認したい場合Firebase Node.jsまたはJavaライブラリ(組み込みの検証メソッドを含む))、IDトークン(JWT)が以下に準拠していることを確認する必要があります。
"RS256"
_と等しいalg
(アルゴリズム)クレームがあります。aud
(オーディエンス)クレームがあります。iss
(発行者)クレームが_"https://securetoken.google.com/<projectId>"
_と等しくなります。sub
(サブジェクト)クレームがあります。これはそのFirebaseユーザーのuid
であることに注意してください。https://www.googleapis.com/robot/v1/metadata/x509/[email protected]
_にリストされている公開キーの1つに対応するkid
(キーID)クレームがあります。Goの場合、 _jwt-go
_ を使用してクライアントIDトークンをデコードおよび検証できるようです。
Firebaseでは、_custom tokens
_の検証が許可されていません。ユーザーがカスタムトークンを使用してサインインすると、_id tokens
_の検証が許可されます。私と同じように、Firebaseカスタムトークンを他のサービスに渡してバックエンドで認証する場合、カスタムトークン検証はあなたにあります!また、Googleサービスアカウント_X509 cert
_は適切な形式ではありません。これらの\n (new line)
区切り文字は、テキストエディターで新しい行に置き換えられません(vim
を使用します)。したがって、私がしたことはこれです:
_ val factory = CertificateFactory.getInstance("X.509")
val certificateFile = this.getClass.getResourceAsStream(Play.current.configuration.getString("firebase.certificate").get)
val publicKey = factory.generateCertificate(certificateFile).asInstanceOf[X509Certificate].getPublicKey
val claimBody = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(compactJws).getBody
_
\n
_を新しい行に置き換えますお役に立てば幸いです!