使用 firebase 令牌在客户端中查询 API

Use firebase tokens to query an API in a client

我使用 firebase 身份验证来保护我的 ASP.NET 核心 api。

我实际上将用户存储在我 API 使用的数据库中。请注意,在我的数据库中,google 标识符是由 firebase 身份验证生成的 uid,而经典标识符(登录名 + 密码)是在我的 API.

中生成的

当用户连接到 Google 时,令牌在客户端创建 (Angular) 所以我将它发送到我的 API (当然我不存储它), 我只是检查令牌是否有效以及令牌中包含的 id 是否对应于存储在我的数据库中的其中一个用户的标识符。

在我的客户端中,google 身份验证:

async GoogleAuth() {
try {
  return new Promise((resolve, reject) => {
    signInWithPopup(this.auth, this.provider).then(() => {
      this.auth.onAuthStateChanged((user) => {
        if (user) {
          user
            .getIdToken()
            .then((idToken) => {
              this.sendTokenUserGoogleToAPI(user, idToken)
                .then((data: any) => {
                  localStorage.setItem('token', data.token);
                  resolve(data);
                })
                .catch((error) => {
                  console.log("googleAuth : " + error)
                  reject(error);
                });
            })
            .catch(() => { });
        }
      });
    });
  });
} catch (e) { }

}

对于经典连接(登录名+密码),数据直接发送到我的API,我在后端创建一个带有用户 ID 的个性化令牌,然后将令牌发送给生成的客户端从令牌到个性化令牌。

在我的 API 中,对于经典身份验证:

 [HttpPost]
    [ActionName("signin")]
    public async Task<ActionResult> SignIn([FromBody] UserLoginViewModel userModel)
    {
        var user = await _context.Users.FirstOrDefaultAsync(u =>
            u.Login == userModel.Login && u.Password == userModel.Password);
        if (user == null)
        {
            _logger.LogWarning("Connection attempt failed.");
            return NotFound(new { message = "User or password invalid." });
        }
        if (user.IsLocked)
        {
            return new ObjectResult(new { message = "Your account has been blocked." }) { StatusCode = 403 };
        }
        var token = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(user.UserId);
        var login = user.Login;
        return Ok(new
        {
            login,
            token
        });
    }

在我的客户端中,当我从 API

收到令牌时
signInWithCustomToken(getAuth(),token)
    .then((userCredential) => {
      const user = userCredential.user;
      console.log(token)
        user!.getIdToken(true).then((idToken) => {
          localStorage.setItem('token', idToken)
      }).catch((error) => {
        console.log(error)
        })
    })

所以我猜我不应该在后端生成令牌,而应该只 return 在客户端生成令牌的 ID?我在客户端重新生成令牌,以便用户可以访问聊天

对于我的客户,我是通过每次查询 firebase 来获取令牌更好,还是我将此令牌存储在本地以便能够在我的请求中使用它更好?

目前,我将它存储在本地,但我认为如果令牌更改或攻击者修改他的令牌可能会出现问题,因为我感谢 firebase 验证用户已连接,如果本地令牌更改, firebase 总是会说用户已登录,但在我的 api 中令牌将无效。

您从 Firebase 身份验证获得的 ID 令牌是一个 exp property/claim,它会向您显示它的有效期。 Firebase 自己的 SDK 会在令牌过期前约 5 分钟刷新令牌,因此您的代码可能也应该这样做。事实上,如果您监听 ID 令牌何时更改 (Android web),您不必自己强制刷新,只需借助 SDK 已经为您完成的工作即可。