Node.js + Firebase:如何在服务器端检查用户是否已身份验证

huangapple go评论76阅读模式
英文:

Nodejs + firebase: how to check if user is authenticated server side

问题

用户已在客户端使用Firebase SDK进行身份验证。

在服务器端,使用Node.js,并安装了Firebase SDK。这个服务器端的代码是有效的,因为我能够使用数据库:

var firebase = require("firebase/compat/app");
require("firebase/compat/database");
require("firebase/compat/auth");

const firebaseConfig = {
  apiKey: "Axxx4",
  authDomain: "movtxxxom",
  projectId: "moxxx2",
  storageBucket: "movxxom",
  messagingSenderId: "14xx9",
  appId: "1:1xxxea13c",
  measurementId: "GxxFL",
  databaseURL: "httpxxx/",
};

// 初始化 Firebase
firebase.initializeApp(firebaseConfig);

这段代码是有效的。

以下是一个(fastify)路由,我想要获取用户信息:

fastify.get("/login-success", async (request, reply) => {
  // 返回视图

  const user = firebase.auth().currentUser;
  console.log(user);
  return reply.view("/templates/login-success.ejs", {
    text: "登录成功",
  });
});

用户变量始终为null。

如何正确处理这种情况?

  • 是否有我不知道的Firebase函数可以检索当前用户信息?
  • 如果是的话,我应该将什么传递给请求?

更一般地说,如何处理这种情况?

英文:

User is authenticated on client side with firebase sdk.

on server side, there is nodejs with also the sdk installed. This server code is valid as i'm able to use the db:

var firebase = require("firebase/compat/app");
require("firebase/compat/database");
require("firebase/compat/auth");

const firebaseConfig = {
  apiKey: "Axxx4",
  authDomain: "movtxxxom",
  projectId: "moxxx2",
  storageBucket: "movxxom",
  messagingSenderId: "14xx9",
  appId: "1:1xxxea13c",
  measurementId: "GxxFL",
  databaseURL: "httpxxx/",
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

This code is valid.

And here is a (fastify) route where I want to get user information:

fastify.get("/login-success", async (request, reply) => {
 // Return View

 const user = firebase.auth().currentUser;
 console.log(user);
 return reply.view("/templates/login-success.ejs", {
   text: "Log in success",
 });
});

The user variable is always null.

How is the proper way to handle this?

  • Is there a firebase function i'm unaware of that could retrieve current user info ?
  • Should I pass something to the request, if yes what?

More generally how to handle this situation?

答案1

得分: 0

为了在服务器端验证用户身份,您需要在客户端生成JWT,然后在服务器上进行验证。
首先,在客户端生成IdToken

接下来,在请求中发送此令牌到服务器。您可以使用Bearer身份验证(将其作为HTTP标头发送。Authorization: Bearer )。

在服务器上,您可以使用任何JWT库来验证令牌。
如果您想要使用Firebase SDK,那么您必须使用正确的版本。
"firebase/compat/auth"适用于客户端。您需要Firebase Admin SDK,
这里是如何使用Firebase Admin SDK验证ID令牌的链接

英文:

In order to verify a user server side, you will need to generate a JWT client side and then verify that on the server.
First, on the client side generate IdToken

Next, send along the token in your request to the server. You can use bearer authentication for this (send as HTTP header. Authorization: Bearer <token>)

On the server you can use any JWT library to verify the token.
If you want to use the Firebase SDK then you must use the correct one.
"firebase/compat/auth" is for client side. You need Firebase Admin SDK,
here is the link on how to Verify ID tokens using the Firebase Admin SDK

答案2

得分: 0

awannabeengineer是正确的。这是一个概念验证(在用户身份验证和信息检索之后必须对服务器端代码进行适配)。

服务器端:

fastify.post("/authcheck", async (request, reply) => {
  try {
    const idToken = request.body.idToken;
    console.log(idToken);
    const decodedToken = await firebase.auth().verifyIdToken(idToken);
    const uid = decodedToken.uid;

    // 从Firebase获取用户数据
    const user = await firebase.auth().getUser(uid);
    console.log(user.displayName);
    return user; // 执行其他操作
  } catch (error) {
    console.error("验证ID令牌时出错:", error);
    reply.code(401).send({ error: "未经授权的访问" });
  }
});

前端:

async function sendTokenToServer() {
  try {
    const idToken = await firebase
      .auth()
      .currentUser.getIdToken(/* forceRefresh */ true);

    // 通过HTTPS将令牌发送到后端
    const response = await fetch("/authcheck", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ idToken }),
    });

    if (!response.ok) {
      throw new Error("网络响应不正常");
    }

    const data = await response.json();

    // 在此处理服务器响应
    console.log("用户ID:", data.userId);
  } catch (error) {
    // 处理错误
    console.error("错误:", error);
  }
}

sendTokenToServer();

是的,我现在在服务器端使用Firebase管理员("firebase"是服务器上的实例)。

英文:

awannabeengineer was right. Here is a proof of concept (adaptation must be made on server side code after user authentication and info are retrieved).

Server:

fastify.post(&quot;/authcheck&quot;, async (request, reply) =&gt; {
  try {
    const idToken = request.body.idToken;
    console.log(idToken);
    const decodedToken = await firebase.auth().verifyIdToken(idToken);
    const uid = decodedToken.uid;

    // Get user data from Firebase
    const user = await firebase.auth().getUser(uid);
    console.log(user.displayName);
    return user; // DO SOMETHING ELSE
  } catch (error) {
    console.error(&quot;Error verifying ID token:&quot;, error);
    reply.code(401).send({ error: &quot;Unauthorized access&quot; });
  }
});

Frontend:

 async function sendTokenToServer() {
            try {
              const idToken = await firebase
                .auth()
                .currentUser.getIdToken(/* forceRefresh */ true);

              // Send token to your backend via HTTPS
              const response = await fetch(&quot;/authcheck&quot;, {
                method: &quot;POST&quot;,
                headers: {
                  &quot;Content-Type&quot;: &quot;application/json&quot;,
                },
                body: JSON.stringify({ idToken }),
              });

              if (!response.ok) {
                throw new Error(&quot;Network response was not ok&quot;);
              }

              const data = await response.json();

              // Handle server response here
              console.log(&quot;User ID:&quot;, data.userId);
            } catch (error) {
              // Handle error
              console.error(&quot;Error:&quot;, error);
            }
          }

          sendTokenToServer();

And yes I now use firebase admin on the server side ("firebase" is the instance on server).

huangapple
  • 本文由 发表于 2023年7月18日 01:05:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76706674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定