我有一个 createUser 函数,它发送一个 axios req 来表达,并需要一些时间来完成创建一个经 Firebase 身份验证的用户,创建一个令牌并将令牌作为 cookie 发送回用户。
我还有一个 getLoggedIn 函数,它接收 cookie 并将其发送给 express 以进行身份验证,然后相应地调整我的 authContext。
我的函数如下所示:await createUser(registerData ).then(() => getLoggedIn())
我的问题是 getLoggedIn() 在 createUser 完成发回 cookie 之前被提前调用。知道如何解决这个问题吗?有没有办法监听 cookie 的变化?我没有看到其他人这样做,我的方法一般是错误的吗?
感谢您的帮助。
新建用户表单
const { getLoggedIn, loggedIn } = useContext(AuthContext);
const register = async (e) => {
e.preventDefault();
const registerData = {
email,
password,
passwordVerify,
};
try {
await createUser(registerData).then(() => getLoggedIn());
} catch (err) {
console.log(err);
}
}};
创建用户
export const createUser = async (props) => {
console.log("New User Creation Initiated", props);
const { email, password, passwordVerify } = props;
let userObject = { tokenId: null };
try {
await firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(({ user }) => {
console.log("createUserWithEmailAndPassword", user);
user
.getIdToken()
.then((tokenId) => {
userObject = { tokenId: tokenId };
axios.post(`${domain}/auth`, userObject);
})
.catch((err) => console.log("new user error", err));
})
.catch((err) => {
console.log("createUser Error", err);
});
return;
} catch (err) {
console.log("New User Creation Error: ", err);
}
};
验证上下文
const AuthContextProvider = (props) => {
console.log("AuthContextProvider Initiated");
const [loggedIn, setLoggedIn] = useState(null);
const getLoggedIn = async () => {
console.log("getLoggedIn Initiated");
let validatedUser = await axios.get(`${domain}/auth/loggedIn`);
console.log("AuthContextProvider validatedUser", validatedUser);
setLoggedIn(validatedUser.data);
};
useEffect(() => {
getLoggedIn();
}, []);
return (
<AuthContext.Provider value={{ loggedIn, getLoggedIn }}>
{props.children}
</AuthContext.Provider>
);
};
快递
router.post("/", async (req, res) => {
console.log("---User signup initiated---");
try {
const { tokenId } = req.body;
console.log("tokenId passed from frontend: ", tokenId);
admin
.auth()
.verifyIdToken(tokenId)
.then((decodedToken) => {
const { email, uid } = decodedToken;
console.log("Fetched UID: ", uid);
console.log("Fetched email: ", email);
const Users = db.collection("users");
Users.doc(`${uid}`).set({
email: email,
posts: [],
});
console.log("---jwt signing initiated---");
const token = jwt.sign(
{
user: { email, uid },
},
process.env.JWT_SECRET
);
console.log("token log: ", token);
return res
.cookie("token", token, {
httpOnly: true,
sameSite: "none",
secure: true,
})
.send();
});
} catch (err) {
console.log(err);
}
});
router.get("/loggedIn", (req, res) => {
console.log("login validation initiated");
try {
const token = req.cookies.token;
if (!token) {
console.log("no token cookie");
return res.json(null);
}
const validatedUser = jwt.verify(token, process.env.JWT_SECRET);
console.log("Token cookie: ", validatedUser);
res.json(validatedUser);
} catch (err) {
console.log("loggedIn", err);
}
});
答案 0 :(得分:0)
您可以在 AuthContext 中像这样使用 onAuthStateChanged。
const AuthContextProvider = (props) => {
console.log("AuthContextProvider Initiated");
const [loggedIn, setLoggedIn] = useState(null);
const getLoggedIn = async () => {
console.log("getLoggedIn Initiated");
let validatedUser = await axios.get(`${domain}/auth/loggedIn`);
console.log("AuthContextProvider validatedUser", validatedUser);
setLoggedIn(validatedUser.data);
};
const handleAuthStateChanged = user => {
if(user) { //user login
getLoggedIn()
} else { //user logout
setLoggedIn(null)
}
}
useEffect(() => {
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
handleAuthStateChanged(user)
})
return unsubscribe
}, []);
return (
<AuthContext.Provider value={{ loggedIn, getLoggedIn }}>
{props.children}
</AuthContext.Provider>
);
};
答案 1 :(得分:0)
在我的 createUser 函数中,我移动了 axios 调用并将其返回到 firebase.auth() 承诺序列之外。现在似乎可以工作了。
export const createUser = async (props) => {
console.log("New User Creation Initiated", props);
const { email, password, passwordVerify } = props;
let userObject = { tokenId: null };
try {
await firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(({ user }) => {
console.log("createUserWithEmailAndPassword", user);
user
.getIdToken()
.then((tokenId) => {
userObject = { tokenId: tokenId };
})
.catch((err) => console.log("new user error", err));
})
.catch((err) => {
console.log("createUser Error", err);
});
return axios.post(`${domain}/auth`, userObject);
} catch (err) {
console.log("New User Creation Error: ", err);
}
};