Firebase管理员sdk:idToken或授权的自定义令牌验证

时间:2018-04-21 14:08:20

标签: javascript firebase firebase-authentication access-token firebase-admin

我在后台服务器上创建自定义令牌,而登录及以下是代码:

UserSchema.methods.generateAuthToken = function() {
 var user = this;
 var access = "auth";

 return firebaseAdmin.default
  .auth()
  .createCustomToken(user._id.toHexString())
  .then(function(token) {
    user.tokens = user.tokens.concat([{ access, token }]);
    return user.save().then(() => {
      return token;
    });
  });
};

并将此令牌存储在mongodb中,并通过名为" x-auth"的标题将其发送回客户端然后将其存储在cookie中。

在客户端,使用此令牌进行如下登录:

axios({
  url: "/api/users/login",
  method: "POST",
  data: {
    email: data.email,
    password: data.password
  }
}).then(res => {
  Cookies.set("x-auth", res.headers["x-auth"], { expires: 7 });
  return firebase
    .auth()
    .signInWithCustomToken(res.headers["x-auth"])
    .then(response => {
      console.log("CA", response);
      response
        .getIdToken()
        .then(idToken => {
          Cookies.set("idToken", idToken, { expires: 7 });
        })
        .catch(e => {});
      dispatch(
        login({
          token: Cookies.get("x-auth")
        })
      );
    });
});

现在为了调用api来获取所有用户,我将这些令牌,自定义令牌和idToken发送回服务器:

const authenticate = (req, res, next) => {
const token = req.header("x-auth");
const idToken = req.header("idToken");
User.findByToken(token, idToken)
.then(user => {
  if (!user) {
    return Promise.reject({
      message: "no user found with the associated token!"
    });
  }
  req.user = user;
  req.token = token;
  next();
})
.catch(e => {
  res.status(401).send(setErrorMessage(e.message));
});
};

findByToken如下:

UserSchema.statics.findByToken = function(token, idToken) {
var User = this;
return firebaseAdmin.default
.auth()
.verifyIdToken(idToken)
.then(function(decodedToken) {
  var uid = decodedToken.uid;
  return User.findOne({
    _id: uid,
    "tokens.access": "auth",
    "tokens.token": token
  });
})
.catch(function(e) {
  return Promise.reject(e);
});
};

为什么我必须发送这两个令牌进行授权,这里的概念是否有任何问题。

  

https://www.tensorflow.org/mobile/tflite/demo_android

     

警告:Firebase管理SDK中包含的ID令牌验证方法旨在验证来自客户端SDK的ID令牌,而不是您使用管理SDK创建的自定义令牌。有关详细信息,请参阅Auth令牌。

请说明我是否可以验证自定义令牌而不是idToken来检索userId并将其与DB匹配,而不是为了一个目的使用不同的令牌,或者我在这里做错了而且不应该存储自定义令牌在DB内部,还有其他一些方法。

现在,在我尝试获取所有用户的某个时候,它说:

  

Firebase ID令牌已过期。从您的客户端应用程序获取新的令牌,然后重试(auth / id-token-expired)。有关如何检索ID令牌的详细信息,请参阅https://firebase.google.com/docs/auth/admin/verify-id-tokens

1 个答案:

答案 0 :(得分:2)

使用令牌时,您需要区分每个令牌及其用途,每个令牌都有相关属性。

Custom Tokens:这些令牌将在服务器中生成(正如您所做),并在客户端用于对客户端进行身份验证。这些令牌在一小时后过期。

会话ID令牌:(我称之为“会话ID令牌”只是为了区分它)当客户端与任何身份验证提供程序进行身份验证时,SDK将交换用于会话的ID令牌的信息。这同样适用于自定义令牌,其中SDK交换ID令牌的自定义令牌。 ID令牌也是短暂的,将在一小时后过期。获取ID令牌时,SDK还会收到一个刷新令牌,用于refreshing会话ID令牌。在对Firebase进行经过身份验证的请求时会使用ID令牌。

用于验证的ID令牌:要获得此令牌,您需要调用函数“getIDToken”(对于Web)。此函数将返回一个ID令牌,该令牌仅可用于验证从客户端到服务器的请求。与其他令牌类似,此一个令牌在一小时后到期。当调用getIDToken时,如果当前过期,该函数将请求新的。

要验证ID令牌,您必须使用上述令牌。如果您尝试使用会话ID令牌或自定义令牌,您将收到错误。如果您尝试使用过期的ID令牌,则同样适用。

刷新ID令牌的所有调用和任务都由幕后的SDK处理。

存储这些令牌并不是一个好习惯,因为它们将在一小时后过期,如果您调用适当的函数来获取Latets令牌并传递正确的ID令牌以进行验证,则更好。

最后,您可以在这些链接中找到用于生成custom tokenID Token以进行验证的属性。