基于 Firebase cookie 的身份验证不适用于非快速服务器

时间:2021-03-05 01:51:41

标签: javascript firebase firebase-authentication google-cloud-functions

按照 this firebase 文档中的代码,我正在尝试实现基于 cookie 的身份验证,以便我可以在多个子域中传递 cookie。 这是我用于登录和检查会话文件的主要功能:

exports.SignInUser = functions.https.onRequest((req, res) => {
    corsHandler(req, res, async () => {
        const idToken = req.body.idToken.toString();
        
        const expiresIn = 60 * 60 * 24 * 5 * 1000;
        admin
            .auth()
            .createSessionCookie(idToken, { expiresIn })
            .then(
            sessionCookie => {
                const options = {
                    maxAge: expiresIn,
                    httpOnly: true,
                    secure: true
                };
                res.cookie('session', sessionCookie, options);
                res.json({
                    status: "ok"
                })
            },
            error => {
                res.json({
                    status: "error",
                    message: "Unauthorized request!"
                })
            });
    })
})

exports.checkSession = functions.https.onRequest((req, res) => {
    corsHandler(req, res, async () => {
        const sessionCookie = req.cookies.session || '';
        admin
            .auth()
            .verifySessionCookie(sessionCookie, true)
            .then(decodedClaims => {
                res.json({
                    status: "ok",
                    data: {
                        decodedClaims
                    }
                })
            })
            .catch((error) => {
                res.json({
                    status: "error",
                })
            });
    })
})

这是 login.html 文件:

<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-database.js"></script>

<script>
    firebase.initializeApp({
        apiKey: "...",
        authDomain: "...",
        databaseURL: "...",
        projectId: "...",
        storageBucket: "...",
        messagingSenderId: "..."
    });

    $(function() {
        firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE);

        function postIdTokenToSessionLogin(idToken) {
            $.ajax({
                url: "http://localhost:5001/...-fea6a/us-central1/SignInUser",
                type: 'post',
                data: {
                    idToken,
                },
                dataType: 'json',
                success: function(data) {
                    console.log(data)
                }
            });
        }

        $.ajax({
            url: "http://localhost:5001/...-fea6a/us-central1/checkSession",
            type: 'post',
            success: function(data) {
                if(data.status === "ok"){
                    window.location.href = "/";
                } else {
                    $("#loader-wrapper").hide();
                    $("#mainrow").fadeIn();
                }
            },
            error: function(){
                $("#loader-wrapper").hide();
                $("#mainrow").fadeIn();
            }
        });

        $("#signinbtn").on("click",() => {
            let errormessage = "";
            const email = $("#email").val();
            const password =  $("#password").val();

            if(email.length == 0) errormessage += "Enter a valid email.<br>";
            if(password.length == 0) errormessage += "Enter a valid password.<br>";

            if(errormessage.length==0){
                $("#signinbtn").prop('disabled', true);

                firebase.auth().signInWithEmailAndPassword(email, password).then(({user}) => {
                    return user.getIdToken().then(idToken => {
                        return postIdTokenToSessionLogin(idToken);
                    })
                })
                .then(() => {
                    return firebase.auth().signOut();
                })
                .catch(function(error) {
                    const errorCode = error.code;
                    const errorMessage = error.message;
                    $("#signinbtn").prop('disabled', false);
                    showMessage(errorMessage);
                });
            } else {
                $("#signupbtn").prop('disabled', false);
                showMessage(errormessage);
            }
        })

    });
</script>

当我尝试此操作时出现此错误: Cannot read property 'session' of undefined

我研究并发现在对外部快递进行身份验证时没有会话。所以我尝试了这个方法来代替函数:

exports.SignInUser = functions.https.onRequest((req, res) => {
    corsHandler(req, res, async () => {
        const idToken = req.body.idToken.toString();
        
        const expiresIn = 60 * 60 * 24 * 5 * 1000;
        admin
            .auth()
            .createSessionCookie(idToken, { expiresIn })
            .then(
            sessionCookie => {
                const options = {
                    maxAge: expiresIn,
                    httpOnly: true,
                    secure: true
                };
                // res.cookie('session', sessionCookie, options);
                res.set('Set-Cookie', `__session=${sessionCookie};max-age=${expiresIn};HttpOnly,Secure`)
                res.json({
                    status: "ok"
                })
            },
            error => {
                res.json({
                    status: "error",
                    message: "Unauthorized request!"
                })
            });
    })
})

exports.checkSession = functions.https.onRequest((req, res) => {
    corsHandler(req, res, async () => {
        try {
            const sessionCookie = req.cookies.__session || '';
            admin
                .auth()
                .verifySessionCookie(sessionCookie, true)
                .then(decodedClaims => {
                    res.json({
                        status: "ok",
                        data: {
                            decodedClaims
                        }
                    })
                })
                .catch((error) => {
                    res.json({
                        status: "error",
                    })
                });
        } catch (e) {
            console.log(e)
            res.json({
                status: "error",
            })
        }
    })
})

这也不起作用(我得到了 Cannot read property '__session' of undefined

我做错了什么?为什么这不起作用?我应该使用另一种方法,如 JWT 吗?感谢您的建议。

0 个答案:

没有答案