按照 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 吗?感谢您的建议。