如何验证自定义令牌?

How to verify a custom token?

我正在为我的项目使用 firebase 身份验证和功能。我的数据库 api 使用不同的提供商。我需要从 "admin" 函数调用我的数据库。我的服务器设置为通过以下配置验证 firebase 的 jwt 令牌(自定义验证,不能使用 firebase admin):

{
   "type":"RS256",
"jwk_url":"https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com",
   "audience":"<firebase-project-id>",
   "issuer":"https://securetoken.google.com/<firebase-project-id>"
}

这会正确验证 ID 令牌,但无法解析由 admin.auth().createCustomToken 创建的自定义令牌并出现以下错误:

Could not verify JWT: JWSError JWSInvalidSignature

因此我不能使用自定义令牌来验证我的云功能,除非我可以以某种方式验证它们?

我的函数令牌是这样生成的:

  const uid = "function-worker";
  const claims = {
    "https://hasura.io/jwt/claims": {
      "x-hasura-default-role": "function",
      "x-hasura-allowed-roles": ["function"],
      "x-hasura-user-id": uid,
    },
  };
  const jwt = await admin.auth().createCustomToken(uid, claims);

生成的 jwt 然后发送到我的 hasura server as per https://github.com/hasura/graphql-engine/tree/master/community/sample-apps/firebase-jwt

以上指南适用于 id 令牌,但不适用于自定义令牌。关于如何 hasura server handles jwt verification can be found here https://github.com/hasura/graphql-engine/blob/dcab20a5ee388ebd754a7828de1309a3a2e0eaee/docs/graphql/manual/auth/authentication/jwt.rst#generating-jwt-config

的更详细解释

您可以使用 Firebase REST API 在服务器端生成一个 ID 令牌。 https://firebase.google.com/docs/reference/rest/auth

在 firebase 函数上生成一个 id 令牌

1 - 休息 API

import fetch from 'node-fetch';
...
const customToken = await admin.auth().createCustomToken(user.uid);
const tokenURL = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=';

const response = await fetch(tokenURL + API_KEY, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    token: customToken,
    returnSecureToken: true
  })
}).then(r => r.json());

console.log(response.idToken);

2 - 服务器上的 Firebase 客户端

import firebase from "firebase/app";
import "firebase/auth";

admin.initializeApp();
firebase.initializeApp(firebase_config);
...

const token: any = await admin.auth().createCustomToken(user.uid)
.then((customToken: string) =>
  // use custom token to get firebase token
  firebase.auth().signInWithCustomToken(customToken)
    .then((cred: firebase.auth.UserCredential) => cred.user?.getIdToken()))
.catch((e: string) => console.error(e));