[英]Cannot read property 'getIdToken' of null after implementing session cookies in firebase
I implemented cookie sessions on my firebase project using this link.我使用此链接在我的 firebase 项目上实现了 cookie 会话。
I'm trying to get the idToken
in the client side to send it to server side.我正在尝试在客户端获取idToken
以将其发送到服务器端。
Here's the code I'm using on client side:这是我在客户端使用的代码:
$(function(){
$.ajax({
url: "/checkSession",
type: 'post',
success: function(data) {
if(data.status === "ok" && data.user){
const user = data.user;
const emailVerified = user.email_verified;
const uid = user.uid;
if (emailVerified){
firebase.database().ref().child("users").child(uid).child("username").once("value", snapshot => {
const username = snapshot.val();
firebase.auth().currentUser.getIdToken(true).then(idToken => {
// Doesn't work...
})
}).catch(err => {
console.log(err)
});
}
}
}
});
});
And here's the server that checks for the session:这是检查 session 的服务器:
app.post("/checkSession", (req, res, next) => {
const sessionCookie = req.cookies.session || '';
admin
.auth()
.verifySessionCookie(sessionCookie, true)
.then(user => {
res.json({
status: "ok",
user
})
})
.catch((error) => {
res.json({
status: "error",
})
});
})
Everything works except this function: firebase.auth().currentUser.getIdToken(true).then(idToken => {...})
and it's throwing Cannot read property 'getIdToken' of null
error.一切正常,除了这个 function: firebase.auth().currentUser.getIdToken(true).then(idToken => {...})
并且它正在抛出Cannot read property 'getIdToken' of null
错误
UPDATE: Here's the sign-in method I'm using.更新:这是我正在使用的登录方法。 I'm passing false to httpOnly
and secure
since I'm testing it locally.因为我在本地测试它,所以我将 false 传递给httpOnly
并且是secure
的。
app.post("/SignInUser", (req, res, next) => {
const idToken = req.body.idToken.toString();
const expiresIn = 60 * 60 * 24 * 10 * 1000; // 10 days
admin
.auth()
.verifyIdToken(idToken)
.then(function (decodedClaims) {
if (new Date().getTime() / 1000 - decodedClaims.auth_time < 5 * 60) {
return admin.auth().createSessionCookie(idToken, { expiresIn });
}
})
.then(function (sessionCookie) {
const options = { maxAge: expiresIn, httpOnly: false, secure: false};
res.cookie("session", sessionCookie, options);
return res.json({
status: "ok"
})
})
.catch(function (error) {
return res.json({
status: "error",
message: "Unauthorized request!"
})
});
})
UPDATE 2: I use the idToken to verify that the request coming from is actually from the user and not from an external source, here's an example code:更新 2:我使用 idToken 来验证来自用户的请求实际上是来自用户而不是来自外部源,这是一个示例代码:
function getUserSnapshotOrVerifyUserId(username, idToken, cb) {
if (username == null || username.length == 0 || idToken == null || idToken.length == 0)
return cb({
status: "error",
errorMessage: "Missing params."
}, null);
admin.auth().verifyIdToken(idToken).then(decodedToken => {
let uid = decodedToken.uid;
admin.database().ref().child("users").orderByChild("username").equalTo(username).once('value', snapshot => {
if (!snapshot.exists())
return cb({
status: "error",
message: "invalid-profile"
});
snapshot.forEach(child => {
const id = child.val().id;
if (id !== uid)
return cb({
status: "error",
message: "Invalid ID"
});
admin.database().ref("users/" + id).once("value", snapshot => {
if (!snapshot.exists())
return cb({
status: "error",
errorMessage: "user not found."
});
return cb(null, id, snapshot);
});
});
});
}).catch(err => cb({
status: "error",
message: err
}));
}
app.post("/getUserProfile", (req, res, next) => {
const username = req.body.username || req.query.username;
const idToken = req.body.idToken;
getUserSnapshotOrVerifyUserId(username, idToken, (err, id, snapshot) => {
if (err) return res.json(err);
let userdata = {
username: snapshot.val().username,
name: snapshot.val().name,
}
res.json({
status: "ok",
userdata
})
})
})
Firebase auth is asynchronous and you need to wait for it to fully initialize before trying to reference currentUser
. Firebase 身份验证是异步的,您需要等待它完全初始化,然后再尝试引用currentUser
。 Please refer to this answer for more information on how to do that.有关如何执行此操作的更多信息,请参阅此答案。
To put it into simpler terms, you need to listen to onAuthStatusChanged()
and wait for it to return null
or a User
object before calling any function that references currentUser
.简而言之,您需要监听onAuthStatusChanged()
并等待它返回null
或User
object,然后再调用引用当前用户的currentUser
。 I'd give you specific code changes but the relevant section isn't in the question.我会给你具体的代码更改,但相关部分不在问题中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.