var request = require('request');
var username = '';
var password = '';
var url = 'http://207.188.73.88:8000/sap/opu/odata/sap/ZTEE_TIME_SRV/ZTEERESERVESet(Time=time\'PT11H00M00S\',Date=datetime\'2014-03-11T00%3A00%3A00\',Location=\'TAJ\',Number=3)';
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
// i am trying to post data to odata service but the problem is that i could not get valid token from get service to use it in the post method i am first send get method
request(
{
url: url,
headers: {
'Authorization': auth,
'x-csrf-token': 'Fetch',
},
},
function(error, response, body) {
console.log('JSON data ' + response);
console.log('body' + body);
// trying to get the token to use in post
console.log(response.headers);
request(
{
url: url,
headers: {
here it says invalid token
'Authorization': auth,
'X-CSRF-TOKEN': 'u6piLO58XoK6udOkQ5Naww==',
},
method: 'POST',
//Lets post the following key/values as form
form: {
Time: 'PT11H00M00S',
Date: '2014-03-11T00%3A00%3A00',
Location: 'TAJ',
Number: 3,
},
},
function(error, response, body) {
console.log(body);
},
);
},
);
我找到了解决方案。
我尝试使用 POSTMAN 来完成此操作,效果很好。 问题是,当我要求 CSRF 令牌时,它总是给我同样的回报。 但是当我尝试使用节点时,每次都不一样。然后我意识到饼干不见了。
仅此而已,解决方案是至少在
cookie
请求中发送 POST
。
set-cookie
请求的"Fetch"
必须在Post
请求中作为Cookie
旁边的x-csrf-token
发送
我把例子放在typescript中,但是在js中并没有太大变化,想法是一样的。
该示例不是最好的情况,但足以弄清楚它是如何工作的
let headers = {
"Authorization": "Basic " + new Buffer(username + ":" + password).toString("base64"),
"Content-Type":"application/json",
"Accept":"application/json",
"x-csrf-token":"Fetch" // get CSRF Token for post or update
};
// if you are using session vars
if (req.session.headers && req.session.headers.cookie) {
headers['Cookie'] = req.session.headers.cookie;
} else {
req.session.headers = {}; // initialize as object
}
let opts = {
url: "https://{host}:{port}/sap/opu/odata/sap/MD_SUPPLIER_MASTER_SRV",
qs: params1, // params set before, not set in the example
headers: headers,
json: true,
}
request(opts, (error: any, response: any, body: any): any => {
if (!error && response.statusCode === 200) {
if (response.headers["set-cookie"]) {
req.session.headers.cookie = response.headers["set-cookie"]; // store Cookie in session
headers['Cookie'] = req.session.headers.cookie; // set in headers for the next call. I guess this is the part you missed
}
if (response.headers['x-csrf-token']) {
req.session.headers.csrf = response.headers['x-csrf-token']; // store csrf-token in session
headers['x-csrf-token'] = req.session.headers.csrf; // set in headers for the next call
}
let options: request.Options = {
url: "https://{host}:{port}/sap/opu/odata/sap/MD_SUPPLIER_MASTER_SRV/C_BusinessPartnerSupplierEdit",
method: 'POST',
headers: headers,
qs: params2, // params set before
json: true,
}
request(options, (error: any, response: any, body: any): any => {
res.json(body);
});
}
});
问候
感谢@subhan 提出的问题和@Mikel 的回答。 我正在使用 SAP CAP,我希望这会自动处理。 同样的事情也发生在我身上:在 Postman 上工作,但在服务器上不行。
通过在模拟服务上本地工作的默认实现,我可以简单地连接到该服务并创建一个新实体:
const bupa = await cds.connect.to('API_BUSINESS_PARTNER');
...
const result = await bupa.create('A_BusinessPartner',newBupa);
我的旅程是使用 SAP CAP 的 .send() 来添加更多标头,但它不允许我获取响应标头,然后使用 SAP Cloud SDK 的 http-client,我尝试使用库的 csrf 选项,最后使用 Node 的 https (以及 - 30 分钟后 - 不是 http),我可以更好地访问请求属性。最终,我回到这篇文章并使其发挥作用。
我缺少的一件事是“Cookie”标头。我已经发送了“set-cookie”和自己的“x-csrf-token”,但这还不够。 (毕竟不需要“set-cookie”。)
这是生成的 SAP CAP 代码:
const cds = require('@sap/cds');
const { executeHttpRequest } = require('@sap-cloud-sdk/http-client');
// ...
let filledHeaders = {};
const fetchHeader = { "x-csrf-token": "fetch" };
const result = await executeHttpRequest({
destinationName: cds.requires.API_BUSINESS_PARTNER.credentials.destination
},{
method: 'GET',
url: cds.requires.API_BUSINESS_PARTNER.credentials.path + '/A_BusinessPartner?$top=1',
headers: fetchHeader
});
filledHeaders['Cookie'] = result.headers["set-cookie"];
filledHeaders['x-csrf-token'] = result.headers['x-csrf-token'];
console.log(filledHeaders); // in case you want to inspect
Object.assign(req.headers, filledHeaders);
// connect to the service
const bupa = await cds.connect.to('API_BUSINESS_PARTNER');
// send the request with the custom headers
const result = await bupa.send('POST', 'A_BusinessPartner', req.data.newBupa, req.headers);
console.log(result);
一些注意事项: