将 Firebase 身份验证与外部数据库结合使用



我目前正在使用 Firebase 在 React/Node 应用程序中对我的用户进行身份验证,但我也想在我自己的数据库中存储其他用户数据,我通过将 Firebaseuid存储在每个用户上来实现这一点,我想在我的实现中获得一些意见,以确保我走在正确的轨道上。

我的前端代码如下:

  1. 这用作"继续谷歌"按钮上的onClick
const googleSignIn = async () =>
signInWithPopup(auth, new GoogleAuthProvider());
  1. 当上述弹出承诺完成时,auth.onAuthStateChanged将在以下useEffect中触发,这将(在登录/注册时)触发函数applicationAuthentication,传入从 Firebase 返回的用户对象:
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(firebaseUser => {
if (!firebaseUser) {
return dispatch(logUserOut());
}
return applicationAuthentication(firebaseUser);
});
return unsubscribe;
}, []);
  1. applicationAuthentication如下所示:
const applicationAuthentication = async (firebaseUser: User) => {
try {
const idToken = await firebaseUser.getIdToken();
const { data } = await axios.get('/api/users/authenticate/signin', {
headers: {
Authorization: `Bearer ${idToken}`
}
});
const { user, error } = data;
if (error) {
throw new Error(error.message);
}
dispatch(logUserIn({ user, accessToken: idToken }));
} catch (error: any) {
dispatch(setUserError(error.message));
console.log(error.message);
}
};

在我的节点快速服务器中,在路由/api/users/authenticate/signin发生以下情况;这是我使用数据访问方法与我自己的数据库进行通信的地方,createUserfindUserByFirebaseUID并使用令牌中的uid来检查用户是否存在,如果不存在,则创建一个新用户(请注意首先检查的中间件,如下所述):

usersRouter.get(
'/authenticate/signin',
async (req: Request, res: Response, next: NextFunction) => {
try {
const uid = res.locals.uid; // set by token middlewear function
let firstLogin = false;
let user = await findUserByFirebaseId(uid);
if (!user) {
firstLogin = true;
user = await createUser(uid);
}
res.json({ user, firstLogin });
} catch (error) {
next(error);
}
}
);

它使用以下authenticate中间件功能对用户进行身份验证firebase-admin

const authenticate = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const idToken = req.headers.authorization.split(' ')[1];
const decodedToken = await admin.auth().verifyIdToken(idToken);
if (decodedToken) {
const { uid } = decodedToken;
res.locals.uid = uid;
return next();
}
return res.status(400).json({ message: 'Unauthorized Request' });
} catch (error) {
next({ message: 'Invalid Token' });
}
};
app.use(authenticate);

使用uid检查我自己的数据库的总体流程看起来是否正确?我是否正确实现了令牌中间件?

我很想听听对此的任何想法!

是的,您将 ID 令牌从客户端传递到服务器,然后在服务器上对其进行解码(在中间件中)以安全地确定 UID 的方式与 Firebase 自己的服务执行此操作的方式类似。

如果将 ID 令牌传递给其他请求以对其进行授权,请考虑保留最近的原始和解码 ID 令牌的缓存,以防止在每个请求上解码它们。

相关内容

最新更新