Javascript 获取禁止错误:无效的csrf令牌(使用firebase auth、autodesk forge和node.js)
使用firebase auth和autodesk forge时出现问题。为了使用firebase身份验证,我使用csurf创建用户会话的cookie。实现csurf后,我会发现一个错误,即为什么尝试使用autodesk forge功能之一:Javascript 获取禁止错误:无效的csrf令牌(使用firebase auth、autodesk forge和node.js),javascript,node.js,firebase-authentication,ejs,autodesk-forge,Javascript,Node.js,Firebase Authentication,Ejs,Autodesk Forge,使用firebase auth和autodesk forge时出现问题。为了使用firebase身份验证,我使用csurf创建用户会话的cookie。实现csurf后,我会发现一个错误,即为什么尝试使用autodesk forge功能之一: responseText: "{"message":"invalid csrf token","code":"EBADCSRFTOKEN"}" 从第55行指
responseText: "{"message":"invalid csrf token","code":"EBADCSRFTOKEN"}"
从第55行指示的my forgeTree文件(第55行包含的函数在下面用**突出显示),其代码如下:
$(document).ready(function () {
prepareAppBucketTree();
$('#refreshBuckets').click(function () {
$('#appBuckets').jstree(true).refresh();
});
$('#createNewBucket').click(function () {
createNewBucket();
});
$('#createBucketModal').on('shown.bs.modal', function () {
$("#newBucketKey").focus();
});
$('#hiddenUploadField').change(function () {
var node = $('#appBuckets').jstree(true).get_selected(true)[0];
var _this = this;
if (_this.files.length == 0) return;
var file = _this.files[0];
switch (node.type) {
case 'bucket':
var formData = new FormData();
formData.append('fileToUpload', file);
formData.append('bucketKey', node.id);
$.ajax({
url: '/api/forge/oss/objects',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
$('#appBuckets').jstree(true).refresh_node(node);
_this.value = '';
}
});
break;
}
});
});
**function createNewBucket() {
var bucketKey = $('#newBucketKey').val();
jQuery.post({
url: '/api/forge/oss/buckets',
contentType: 'application/json',
data: JSON.stringify({ 'bucketKey': bucketKey }),
success: function (res) {
$('#appBuckets').jstree(true).refresh();
$('#createBucketModal').modal('toggle');
},
error: function (err) {
if (err.status == 409)
alert('Bucket already exists - 409: Duplicated');
console.log(err);
}
});
}**
function prepareAppBucketTree() {
$('#appBuckets').jstree({
'core': {
'themes': { "icons": true },
'data': {
"url": '/api/forge/oss/buckets',
"dataType": "json",
'multiple': false,
"data": function (node) {
return { "id": node.id };
}
}
},
'types': {
'default': {
'icon': 'glyphicon glyphicon-question-sign'
},
'#': {
'icon': 'glyphicon glyphicon-cloud'
},
'bucket': {
'icon': 'glyphicon glyphicon-folder-open'
},
'object': {
'icon': 'glyphicon glyphicon-file'
}
},
"plugins": ["types", "state", "sort", "contextmenu"],
contextmenu: { items: autodeskCustomMenu }
}).on('loaded.jstree', function () {
$('#appBuckets').jstree('open_all');
}).bind("activate_node.jstree", function (evt, data) {
if (data != null && data.node != null && data.node.type == 'object') {
$("#forgeViewer").empty();
var urn = data.node.id;
getForgeToken(function (access_token) {
jQuery.ajax({
url: 'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn + '/manifest',
headers: { 'Authorization': 'Bearer ' + access_token },
success: function (res) {
if (res.status === 'success') launchViewer(urn);
else $("#forgeViewer").html('The translation job still running: ' + res.progress + '. Please try again in a moment.');
},
error: function (err) {
var msgButton = 'This file is not translated yet! ' +
'<button class="btn btn-xs btn-info" onclick="translateObject()"><span class="glyphicon glyphicon-eye-open"></span> ' +
'Start translation</button>';
$("#forgeViewer").html(msgButton);
}
});
});
}
});
}
function autodeskCustomMenu(autodeskNode) {
var items;
switch (autodeskNode.type) {
case "bucket":
items = {
uploadFile: {
label: "Upload file",
action: function () {
uploadFile();
},
icon: 'glyphicon glyphicon-cloud-upload'
}
};
break;
case "object":
items = {
translateFile: {
label: "Translate",
action: function () {
var treeNode = $('#appBuckets').jstree(true).get_selected(true)[0];
translateObject(treeNode);
},
icon: 'glyphicon glyphicon-eye-open'
}
};
break;
}
return items;
}
function uploadFile() {
$('#hiddenUploadField').click();
}
function translateObject(node) {
$("#forgeViewer").empty();
if (node == null) node = $('#appBuckets').jstree(true).get_selected(true)[0];
var bucketKey = node.parents[0];
var objectKey = node.id;
jQuery.post({
url: '/api/forge/modelderivative/jobs',
contentType: 'application/json',
data: JSON.stringify({ 'bucketKey': bucketKey, 'objectName': objectKey }),
success: function (res) {
$("#forgeViewer").html('Translation started! Please try again in a moment.');
},
});
}
以下是firebaseauthentication.js文件:
const signupForm = document.querySelector('#signup-form');
const logout = document.querySelector('#logout');
const loginForm = document.querySelector('#login-form');
// listen for auth status changes
auth.onAuthStateChanged(user =>
{
if (user)
{
console.log("user logged in:", user);
}
else
{
console.log("user logged out");
}
});
if (document.querySelector('#signup-form') !== null)
{
// register
signupForm.addEventListener('submit', (e) =>
{
e.preventDefault();
// get user info
const email = signupForm['signup-email'].value;
const password = signupForm['signup-password'].value;
// register the user
auth.createUserWithEmailAndPassword(email, password).then(cred =>
{
// console.log(cred.user);
signupForm.reset();
});
});
}
else if (document.querySelector('#login-form') !== null)
{
document
.getElementById("login-form")
.addEventListener("submit", (event) =>
{
event.preventDefault();
const login = loginForm['login-email'].value;
const password = loginForm['login-password'].value;
firebase
.auth()
.signInWithEmailAndPassword(login, password)
.then((
{
user
}) =>
{
return user.getIdToken().then((idToken) =>
{
return fetch("/sessionLogin",
{
method: "POST",
headers:
{
Accept: "application/json",
"Content-Type": "application/json",
"CSRF-Token": Cookies.get("XSRF-TOKEN"),
},
body: JSON.stringify(
{
idToken
}),
});
});
})
.then(() =>
{
// loginForm.reset();
return firebase.auth().signOut();
})
.then(() =>
{
window.location.assign("/view");
});
return false;
});
}
//logout
logout.addEventListener('click', (e) =>
{
e.preventDefault();
auth.signOut().then(() =>
{
window.location.assign("/");
});
});
以及html集成:
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-firestore.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@rc/dist/js.cookie.min.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-analytics.js"></script>
<script> id="fbauth"
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
var firebaseConfig =
{
apiKey: "apinumbersgohere",
authDomain: "firebaseapp.com",
databaseURL: "https:firebasedatabase.com",
projectId: "id",
appId: "id",
measurementId: "id"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
// make auth and firestore references
const auth = firebase.auth();
const db = firebase.firestore();
auth.setPersistence(firebase.auth.Auth.Persistence.NONE);
// update firestore settings
db.settings({
timestampsInSnapshots: true
});
</script>
<p class="text-center text-muted">© Copyright 2020 Obi Vision</p>
<script src="/public/js/fbauth.js"></script>
</body>
</html>
id=“fbauth”
//您的web应用程序的Firebase配置
//对于Firebase JS SDK v7.20.0及更高版本,measurementId是可选的
var firebaseConfig=
{
apiKey:“apinumbersgohere”,
authDomain:“firebaseapp.com”,
databaseURL:“https:firebasedatabase.com”,
projectd:“id”,
appId:“id”,
度量标准:“id”
};
//初始化Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
//生成auth和firestore引用
const auth=firebase.auth();
const db=firebase.firestore();
auth.setPersistence(firebase.auth.auth.Persistence.NONE);
//更新firestore设置
数据库设置({
时间戳:对
});
©版权所有2020 Obi Vision
我怀疑forgetree api以某种方式获取了我正在生成的csurf cookie,而不是它自己的实例化cookie,但我太笨了,无法发现问题所在。任何愿意帮助我的人都会帮上大忙,你根本不知道Firebase hosting会删除除会话之外的所有cookie,因此你需要在使用会话cookie的任何地方进行更改,如下所示
,,
const sessionCookie = req.cookies.__session || "";
...
res.clearCookie("__session");
也可能需要在下面更新以添加
app.get("/", function(req, res)
{
res.clearCookie("__session");
res.render("login");
});
今天我在不同的页面上遇到了与您相同的错误。谢谢!“res.clearCookie(“\uu session”);”成功了!你能把它标为答案吗?我试过了,但我还没有得到足够的分数。你得为我的第一个问题投票,给我这个特权
app.get("/", function(req, res)
{
res.clearCookie("__session");
res.render("login");
});