javascript - 在 Firebase 中实现 session cookie 后无法读取属性 'getIdToken'

标签 javascript node.js firebase firebase-realtime-database firebase-authentication

我使用 this 在我的 firebase 项目上实现了 cookie session 关联。
我正在尝试获取 idToken在客户端将其发送到服务器端。
这是我在客户端使用的代码:

$(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)
                    });
                }
            }
        }
    }); 
});
这是检查 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",
            })
        });
})
除此功能外,一切正常:firebase.auth().currentUser.getIdToken(true).then(idToken => {...})它正在抛出Cannot read property 'getIdToken' of null错误。
更新:这是我正在使用的登录方法。我将 false 传递给 httpOnlysecure因为我在本地测试它。
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!"
            })
        });
})
更新 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 身份验证是异步的,您需要等待它完全初始化,然后再尝试引用 currentUser .请引用this answer有关如何执行此操作的更多信息。
通俗点说,你需要听onAuthStatusChanged()并等待它返回nullUser调用任何引用 currentUser 的函数之前的对象.我会给你具体的代码更改,但相关部分不在问题中。

关于javascript - 在 Firebase 中实现 session cookie 后无法读取属性 'getIdToken',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66734890/

相关文章:

javascript - 通过codeigniter中的html onblur验证用户名

macos - 重启后找不到 npm 命令

javascript - 如何正确组织 JavaScript 代码?

php - 如何将 css 代码存储在与 Javascript 一起使用的 php 变量中

javascript - AngularJS:多个异步调用 - 如何

javascript - Node js : error while identifying type of directory member

javascript - setTimeout 如何工作?

ios - 应用程序将数据重置为零,即使它存储在 firebase 上

android - 在 firebase 中实现电话和电子邮件身份验证以供一次性使用的最佳方法?

java - 确保先调用 FirebaseApp.initializeApp(Context)