Javascript RESTAPI与谷歌Firebase认证&;使用承载令牌的函数

Javascript RESTAPI与谷歌Firebase认证&;使用承载令牌的函数,javascript,firebase,firebase-authentication,google-cloud-functions,firebase-admin,Javascript,Firebase,Firebase Authentication,Google Cloud Functions,Firebase Admin,快速背景:我正在编写一个被认为是“独立”使用的API,即没有涉及前端。API访问应该可以直接从邮递员或Curl处进行,并在认证头中使用承载令牌 我在看Google Firebase时认为它可能非常适合,因为所有的身份验证都是“内置的”,并且直接与Google云功能兼容。 然而,经过一个周末的实验后,我似乎不知道如何实现RESTAPI(使用Google云函数),用户可以(在web界面中)请求API令牌与API交互。 我不想自己处理身份验证。我真的很想对API使用Firebase身份验证 以下是最终

快速背景:我正在编写一个被认为是“独立”使用的API,即没有涉及前端。API访问应该可以直接从邮递员或Curl处进行,并在认证头中使用承载令牌

我在看Google Firebase时认为它可能非常适合,因为所有的身份验证都是“内置的”,并且直接与Google云功能兼容。 然而,经过一个周末的实验后,我似乎不知道如何实现RESTAPI(使用Google云函数),用户可以(在web界面中)请求API令牌与API交互。 我不想自己处理身份验证。我真的很想对API使用Firebase身份验证

以下是最终流程的外观:

  • 用户通过标准Firebase身份验证过程登录到web界面
  • 用户单击类似“请求API密钥”的内容,并获得web界面中显示的密钥(例如abc…)。由Firebase身份验证生成的
  • 用户可以通过诸如curl等方式向Google Cloud函数中托管的API发出请求,只需设置授权头(承载abc…),该令牌的“验证”由Firebase身份验证处理
  • 以下是我已经尝试生成令牌的内容:

    admin.auth().createCustomToken(uid)
    .then(function(customToken) {
        console.log(customToken);
    })
    .catch(function(error) {
        console.log('Error creating custom token:', error);
    })
    
    const authenticate = async (req, res, next) => {
    if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
      res.status(403).send('Unauthorized');
      return;
    }
    const idToken = req.headers.authorization.split('Bearer ')[1];
    try {
    
      const decodedIdToken = await admin.auth().verifyIdToken(idToken);
      req.user = decodedIdToken;
      next();
      return;
    } catch(e) {
      console.log(e);
      res.status(403).send('Unauthorized');
      return;
    }
    }
    
    然后将Postman中登录到控制台的令牌设置为承载令牌,然后使用以下功能验证令牌:

    admin.auth().createCustomToken(uid)
    .then(function(customToken) {
        console.log(customToken);
    })
    .catch(function(error) {
        console.log('Error creating custom token:', error);
    })
    
    const authenticate = async (req, res, next) => {
    if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
      res.status(403).send('Unauthorized');
      return;
    }
    const idToken = req.headers.authorization.split('Bearer ')[1];
    try {
    
      const decodedIdToken = await admin.auth().verifyIdToken(idToken);
      req.user = decodedIdToken;
      next();
      return;
    } catch(e) {
      console.log(e);
      res.status(403).send('Unauthorized');
      return;
    }
    }
    
    然后我得到了这个错误

    message: 'verifyIdToken() expects an ID token, but was given a custom token. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.'
    
    我知道,如果我要实现一个web界面,我可以从devtools(?)中获取ID令牌,但该令牌仅在1小时内有效。。。我需要的是一个“无限期”有效的令牌,可以生成并显示给用户

    我想我知道我必须以某种方式使用定制代币,但我不知道如何让它们工作。。。()

    提前非常感谢大家

    最好的
    Rick

    您正在尝试在Firebase和云功能之上构建API管理解决方案。自定义令牌和ID令牌不适用于此目的。自定义令牌仅用于最终用户设备上的用户身份验证凭据,ID令牌表示成功的身份验证响应。两种类型的代币都会在一小时后过期

    如果您需要长寿命的托管API密钥,那么您必须自己实现它们。Firebase中没有任何内置的东西可以在开箱即用。我曾经将这样一个解决方案作为原型来实现,每次用户登录并请求API密钥时,我都会生成一个Firestore文档。然后我使用文档ID作为API密钥,我可以在云函数中验证它

    const apiKey = req.headers.authorization.split('Bearer ')[1];
    const doc = await admin.firestore().collection('apiKeys').doc(apiKey).get();
    if (doc.exists) {
      next();
    }
    
    我还必须实现一些本地API密钥缓存以使其高效工作

    通过使用像googlecloudendpoints()这样的解决方案,您可能可以避免一些这方面的工作,尽管我个人对此没有任何经验。最后,还要看看类似的开源解决方案,它使您能够设置自己的API密钥管理和网关