【发布时间】:2022-01-13 10:06:16
【问题描述】:
我目前正在使用 Firebase 在 React/Node 应用程序中对我的用户进行身份验证,但我还想在我自己的数据库中存储其他用户数据,为此我将 Firebase uid 存储在每个用户上,并且我想就我的实施获得一些意见,以确保我走在正确的轨道上。
我的前端代码如下:
- 这用作“继续使用 Google”按钮上的
onClick:
const googleSignIn = async () =>
signInWithPopup(auth, new GoogleAuthProvider());
- 当上述弹出承诺完成时,
auth.onAuthStateChanged会在以下useEffect中触发,这(在登录/注册时)将触发函数applicationAuthentication,传入从 Firebase 返回的用户对象:
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(firebaseUser => {
if (!firebaseUser) {
return dispatch(logUserOut());
}
return applicationAuthentication(firebaseUser);
});
return unsubscribe;
}, []);
-
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;这是我使用数据访问方法findUserByFirebaseUID 和createUser 与我自己的数据库通信的地方,使用令牌中的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 检查我自己的数据库的整个流程看起来是否正确?我是否正确实现了令牌中间件?
我很想听听对此的任何想法!
【问题讨论】:
-
您想为同一用户存储其他数据吗?喜欢 PII 信息? Firebase Auth 具有自定义字段,您可以在其中添加更多数据,例如另一个对象,并且您可以检索该数据。但是如果你想保存一些不同的东西,比如与用户相关的数据,比如完整的 Item 个性化,你可以只保存 uid,(就像你正在做的那样),它似乎没问题。
-
我感兴趣的数据基本上是自定义用户数据,例如用户名、角色、youtubeChannelURL 等。这些示例是您所说的“完整项目个性化”吗?
-
不,我通常指的是完整的个性化和整个个人资料页面,但是没关系,您也可以将这些字段添加到 firebase auth 自定义字段中。