首页 > 解决方案 > 我可以使用 firebase 对我的单独服务器进行授权吗?

问题描述

我正在建立一个生产就绪的电子商务网站,任何本地供应商都可以上传他们的产品并直接销售给客户。

我正在使用 firebase 对 Gmail 和电话号码进行身份验证。我的前端可以检查用户是否经过身份验证。如果用户已通过身份验证,我如何检查后端?

假设某些路由在客户端受到保护,只有经过身份验证的用户才能访问它们。如果有人使用 say(postman) 并使用这些路线怎么办?无论如何我可以附加我的 jwt 令牌,并且客户只有在他使用他的 gmail 或电话进行身份验证时才会得到它?


const signIn = () => {
  return signInWithPopup(auth, provider)
    .then((result) => {
      // This gives you a Google Access Token. You can use it to access the Google API.
      const credential = GoogleAuthProvider.credentialFromResult(result);
      const token = credential.accessToken;
      console.log(token);
      // The signed-in user info.
      const user = result.user;

      console.log("credential:", credential, "token:", token, "user:", user);
    })
    .catch((error) => {
      // Handle Errors here.
      const errorCode = error.code;
      const errorMessage = error.message;
      // The email of the user's account used.
      const email = error.email;
      // The AuthCredential type that was used.
      const credential = GoogleAuthProvider.credentialFromError(error);
      console.log(errorCode, errorMessage, credential, email);
      // ...
    });
};

这将验证用户是否使用 gmail。我如何使用它来告诉我的后端这个人已经过身份验证,这是他的唯一 ID 和其他信息?

标签: javascriptreactjsfirebase-authentication

解决方案


Express 允许您使用中间件。中间件非常简单:在完成请求期间将执行一些逻辑,您可以配置何时执行该逻辑以及执行什么。

授权中间件将为您提供您正在寻找的确切功能。我给你举个例子:

async function firebaseIdTokenValidationMiddleware(req, res, next) {
  //First, I'll check if the request has the Authorization header and if it contains a Bearer type token
  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith('Bearer ')
  ) {
    //If the reuqest has a token, I'll read it
    const idToken = req.headers.authorization.split('Bearer ')[1];
    if (idToken) {
      try {
        //And I'll use Firebase Auth API to validate the token
        const decodedIdToken = await auth().verifyIdToken(idToken);
        if (decodedIdToken) {
          //If Firebase validates the token, the middleware can allow the next step
          req.authEntity = decodedIdToken;
          return next();
        }
      } 
      //Otherwise, we answer with a "Forbidden" status code
      return res.status(403).json({});
    }
  }

  //If there is no authorization header, we answer with a "Unauthorized" status code
  return res.status(401).json({});
}

显然,您可以个性化错误代码。魔法全部委托给 Firebase Auth API:

auth().verifyIdToken(MY_TOKEN)

此调用验证给定令牌是否由 Firebase Auth 本身颁发,以及它是否有效(例如,它验证令牌是否过期)。在此检查之后,在我的示例中,我将解码的实体保存在请求中:

req.authEntity = decodedIdToken;

如果您需要访问端点路由器中的这些信息,这将非常有帮助。您可以访问此页面以获取 Firebase API 在验证后为您提供的完整参考。

请注意 auth().verifyIdToken() 位于 Admin API 中,因此您需要将其导入您的项目中。

到目前为止,我们所做的只是创建中间件。你仍然需要告诉 Express 使用它。你可以通过两种方式做到这一点。

在单个路由器上指定它:

app.get('/', firebaseIdTokenValidationMiddleware, async(req,res) => {
  //YOUR LOGIC
}

在全球范围内,它被称为应用程序级中间件:

app.use(firebaseIdTokenValidationMiddleware);

推荐阅读