首页 > 解决方案 > 如何在 React Native 上处理 Firebase 过期的身份验证令牌

问题描述

我在我的 react 本机应用程序中使用 firebase 作为后端。所有客户端 API 请求都转到我的 firebase 云函数,这些函数使用 Firebase 处理所有后端逻辑(身份验证、firestore、存储)。对于我的身份验证逻辑,一旦用户使用电子邮件和密码登录,我就会得到一个令牌。令牌存储在 AsyncStorage 中,并添加到后端的每个请求的标头中。

到目前为止一切正常,问题是令牌在 1 小时左右后过期,使用被迫再次登录。我搜索了 firebase 文档和网络,我知道我需要在每个经过身份验证的请求之前请求一个新令牌。问题是我不知道怎么做?

为了提高精度,我对所有需要身份验证的请求使用中间件函数 (isAuthenticated),我在其中验证令牌(这是在我的后端服务器中完成的)。

// Users routes
app.post("/signup", signup);
app.post("/login", login);
app.post("/user/image", isAuthenticated, uploadImage);
app.post("/user", isAuthenticated, addUserDetails);

我的问题是如何实现令牌刷新逻辑,我可以要求一个过期的新令牌吗?提前致谢。

更新:(更多详细信息)这是我首先获取令牌的方式:客户端应用程序(移动+网络)将 REST 请求发送到我的 firebase 函数。例如登录,我有这个功能:

exports.login = (req, res) => {
  const user = {
    email: req.body.email,
    password: req.body.password
  };

  const { valid, errors } = validateLoginData(user);
  if (!valid) return res.status(400).json(errors);

  firebase
    .auth()
    .signInWithEmailAndPassword(user.email, user.password)
    .then(data => {
      return data.user.getIdToken();
    })
    .then(token => {
      return res.json({ token });
    })
    .catch(err => {
      return res
        .status(403)
        .json({ general: "Wrong credentials, please try again" });
    });
};

登录后,客户端会收到令牌并使用 AsyncStorage/LocalStorage 将其存储,以便将其包含在授权标头中。

对于所有经过身份验证的根,我使用此中间件函数检查用户令牌:

exports.isAuthenticated = async (req, res, next) => {
  let idToken;
  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith("Bearer ")
  ) {
    idToken = req.headers.authorization.split("Bearer ")[1];
  } else {
    console.error("No token found");
    return res.status(403).json({ error: "Unauthorized" });
  }
      admin
      .auth()
      .verifyIdToken(idToken)
      .then(decodedToken => {
        req.user = decodedToken;
        return db
          .collection("users")
          .where("userId", "==", req.user.uid)
          .limit(1)
          .get();
      })
      .then(data => {
        return next();
      })
  } catch (err) {
    console.error(err);
  }
};

提前致谢。

标签: firebasereact-nativefirebase-authentication

解决方案


我可以看到有一段时间没有人更新这个,所以我想我会写下我在后端所做的事情来重新验证过期的令牌。这被埋在某个地方,很难找到,因为官方文档没有涵盖这一点。

let body = {
        grant_type: "refresh_token", 
        refresh_token: req.body.refreshToken || null
};

if (!body.refresh_token) {
    return res.status(400).json({
        message: ERROR._400
    })
}

const {data: {refresh_token, id_token}} = await axios.post(`https://securetoken.googleapis.com/v1/tokenkey=${config.apiKey}`, body);

推荐阅读