Node.js HTTPS POST Request Headers - facebook

I want to post a status update to a Facebook Group using Node.js. It seems Node.js doesn't send the header…
var https = require('https');
var options = {
host: 'graph.facebook.com',
port: 443,
path: '/'+group_id+'/feed?access_token='+access_token,
method: 'POST',
headers: { 'message': text }
};
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function(d) {
process.stdout.write(d);
});
});
req.end();
This is the log data:
statusCode: 400
headers: { 'cache-control': 'no-store',
'content-type': 'text/javascript; charset=UTF-8',
expires: 'Sat, 01 Jan 2000 00:00:00 GMT',
p3p: 'CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"',
pragma: 'no-cache',
'www-authenticate': 'OAuth "Facebook Platform" "invalid_request" "(#100) A post to a group must have at least a message or attachment"',
'x-fb-rev': '443252',
'set-cookie': [ 'datr=removed; expires=Tue, 17-Sep-2013 12:18:08 GMT; path=/; domain=.facebook.com; httponly' ],
'x-fb-server': '10.62.5.40',
connection: 'close',
date: 'Sun, 18 Sep 2011 12:18:08 GMT',
'content-length': '115' }
{"error":{"message":"(#100) A post to a group must have at least a message or attachment","type":"OAuthException"}}

I think you need to send the message (the contents of your variable called 'text') in the body of your request, not the head. See this answer for an example of how to do this.

Related

REST API call is unauthorized

I am trying to make a REST API call from my .Net MAUI mobile app.
First I log in, and get a JwtSecurityToken:
JwtSecurityToken JwtToken = new JwtSecurityToken(authenticationResult.IdToken);
Then I try to use it to make a REST API call:
HttpClient client = new ();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken.RawData);
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
This gives me an exception
Response status code does not indicate success: 401 (Unauthorized).
What is wrong or missing here?
ADDED:
Here is the respose:
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
client-request-id: 162ea393-a9b2-4e6b-9786-d6e18d18afb1
Date: Sun, 25 Dec 2022 20:42:26 GMT
request-id: 162ea393-a9b2-4e6b-9786-d6e18d18afb1
Strict-Transport-Security: max-age=31536000
Transfer-Encoding: chunked
Vary: Accept-Encoding
WWW-Authenticate: Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", client_id="00000003-0000-0000-c000-000000000000"
X-Android-Received-Millis: 1672000947348
X-Android-Response-Source: NETWORK 401
X-Android-Selected-Protocol: http/1.1
X-Android-Sent-Millis: 1672000947271
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Central US","Slice":"E","Ring":"3","ScaleUnit":"005","RoleInstance":"CH01EPF000051D6"}}
Content-Type: application/json
}, Trailing Headers:
{
}}
If you are developing your own API, you can then set this flag to true:
.AddJwtBearer(options =>
{
options.IncludeErrorDetails = true;
...
Then you will see a reason in the response why it failed:
HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"

flutter: send Authorization Token along http header

I am making a request in postman with the same URL that i use in my UI code and in the header passing accept and Authorization with bearer token. In postman it is working completely fine and giving desired response but in flutter in my code the token not send to server when i print my header using print(response.headers) it print {x-powered-by: Express, connection: keep-alive, keep-alive: timeout=5, date: Thu, 30 Sep 2021 16:47:57 GMT, content-length: 429, etag: W/"1ad-Nsvj6qTf+5iQsO/n7VuLkLMax/M", content-type: application/json; charset=utf-8} that means the Authorization part not send along the request header how can i send the authorization and token along to http post request ? please guide me it take my long hours but still not working.
here is my code:
var token='somethings';
response = await http.post(uri,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Accept': 'application/json',
'authorization': 'Bearer $token',
},
body: jsonEncode(account[i]));
headers: {
HttpHeaders.authorizationHeader: 'Basic your_api_token_here',
},

API Gate away Is Blocked even when CORS is enabled

I'm trying to make an api to upload images to cloudinary like this
fd.append('photos', file);
fd.append('upload_preset',
CLOUDINARY_UPLOAD_PRESET);
axios({
url: CLOUDINARY_API,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
"Access-Control-Allow-Origin": "*",
'Access-Control-Allow-Headers': 'Origin',
'Access-Control-Allow-Credentials': true
},
data: fd
}).then(function(res) {
console.log(res);
}).catch(function(err) {
console.error(err);
})
})
but i recieve this error from the browser
Access to XMLHttpRequest at 'https://api.cloudinary.com/v1_1/******/mh/upload' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.Blockquote
You will need to remove the three "Access-Control-Allow-*" headers from the request you are sending.
The headers Cloudinary allows for cross-origin requests don't include those headers which you are sending and therefore the browser throws this error.
Below are the headers that are allowed for cross-origin uploads (under Access-Control-Allow-Headers):
curl -sD - -X OPTIONS https://api.cloudinary.com/v1_1/demo/image/upload
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Cache-Control, Content-Disposition, Content-MD5, Content-Range, Content-Type, DPR, Viewport-Width, X-CSRF-Token, X-Prototype-Version, X-Requested-With, X-Unique-Upload-Id
Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS
Access-Control-Max-Age: 1728000
Cache-Control: no-cache
Content-Type: text/plain; charset=utf-8
Date: Sat, 19 Dec 2020 09:49:48 GMT
Server: cloudinary
Status: 200 OK
Vary: Accept-Encoding
X-Request-Id: d1af2a2f8a986d9ebbd1f14399dd409d
X-UA-Compatible: IE=Edge,chrome=1
X-XSS-Protection: 1; mode=block
Content-Length: 0
Connection: keep-alive
EDIT: In addition, Cloudinary API doesn't have a parameter called "photos". The file to upload is sent in the "file" parameter.
Therefore, you would need to replace fd.append('photos', file); with fd.append('file', file);.

(questions about POST requests) Is there a way to send a POST request and then get back the retrieved resource in the event of a 302 externally?

This is a bit confusing but I'm going to try my best to explain it properly, I'll really appreciate an answer to this.
Suppose I've got the endpoint "example.com/login" that displays an HTML page with a login form that upon submitting sends a POST request to "example.com/login" (yes itself) with the credentials (shown below) and then upon successful authentication displays another HTML page (example.com/user/records) that shows your details (for e.g your data records and stuff).
What I plan on doing is accessing the HTML page that shows that data by sending a POST request externally using Javascript with the credentials and then somehow just receiving the HTML for the data records page as a string response as we'd normally get through a GET request (is this even possible?).
upon sending said request it shows this in the network tab:
(Remote Address has been modified to replace all numbers with 0)
Request URL: https://example.com/login
Request Method: POST
Status Code: 302
Remote Address: 000.000.000.000:000
Referrer Policy: strict-origin-when-cross-origin
Response Headers:
cache-control: no-store, no-cache, must-revalidate
content-type: text/html; charset=UTF-8
date: Mon, 30 Nov 2020 22:43:08 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
location: https://example.com/user/records
pragma: no-cache
server: Apache
Request Headers:
:authority: example.com
:method: POST
:path: /login
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en
cache-control: max-age=0
content-length: 47
content-type: application/x-www-form-urlencoded
cookie: roundcube_cookies=enabled; timezone=Asia/Baghdad; resetpasscookie=kUcAf8R5ue5VsOVM; webmailsession=%3af5nnuvNuUHvJaAWn%2c73236ca3fe2776acd45d97c7fffdfd79; whostmgrsession=%3alTiPVRgz7acX0SQG%2c97f0382efe30423a72f3caefec64192f; cpsession=%3arm4IkcjwHaihjbFR%2c859b30622f8d57aebed715dea4d2791e; ci_session=2vofur1iqi6sgrurb1s2dtb5f0tfggi8
origin: https://example.com
referer: https://example.com/login
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
Form Data:
ci_csrf_token:
username: abc
password: 123
first concern: Where on Earth did those cookies even come from?? (if they're set by the server then is there a way I can still do what I plan on doing?)
I just copied that request from the options directly as a Node fetch request and ran it in Visual Studio Code externally (not connected to that website in any way right now) and got this:
(an account with details username: abc, password: 123 exists suppose - I've just replaced the credentials)
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kTransformState)]: [Object]
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'https://example.com/login',
status: 200,
statusText: 'OK',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 2
}
} Headers {
[Symbol(map)]: [Object: null prototype] {
date: [ 'Mon, 30 Nov 2020 22:54:12 GMT' ],
server: [ 'Apache' ],
expires: [ 'Thu, 19 Nov 1981 08:52:00 GMT' ],
'cache-control': [ 'no-store, no-cache, must-revalidate' ],
pragma: [ 'no-cache' ],
'set-cookie': [
'ci_session=06ujfc27fpp73a01nia1dp3pehsskep5; expires=Tue, 01-Dec-2020 00:54:12 GMT; Max-Age=7200; path=/; HttpOnly'
],
upgrade: [ 'h2,h2c' ],
connection: [ 'Upgrade, close' ],
'transfer-encoding': [ 'chunked' ],
'content-type': [ 'text/html; charset=UTF-8' ]
}
}
2nd concern) Why was I greeted with code 200 here, and 302 on the browser?
Anyways, I planned on authenticating myself by copying the post request that would've been sent through the login form and supplying various correct credentials so I could access their details using Javascript externally, and then manipulate them.
If this can't work then is there any other way to do this? Or if it can, then how?
I realized it could be solved in some cases by providing {"redirect": "follow"} to the options when using fetch.

Ionic 2 http post request remove default headers

I am new to Ionic 2. I make a http post request to my Spring Rest-api. As header I need to set the 'content-type': 'application/json', but the Ionic 2 sets automatically the content-type to application/json; charset=UTF-8, which is causing my REST service to respond with 415 status.
Here is my code:
register(user: User){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post(apiUrl + 'users', user, {headers:headers})
.then((response: Response) => {
console.log(response);
console.log(JSON.stringify(user, null , 2));
console.log(JSON.stringify(headers, null, 2));
});
}
Here is the error I get when making the post request:
[00:46:35] error opening ws message: {"category":"console","type":"log","data":["error:
",{"status":415,"url":"**MY_URL**","headers":{"x-android-received-millis":"1512686795738","x-frame-options":"DENY","pragma":"no-cache","content-type":"application/json;charset=UTF-8","x-content-type-options":"nosniff","date":"Thu,
07 Dec 2017 22:46:35 GMT","strict-transport-security":"max-age=31536000 ; includeSubDomains","via":"1.1
vegur","connection":"keep-alive","x-android-sent-millis":"1512686795652","cache-control":"no-cache,
no-store, max-age=0,
must-revalidate","transfer-encoding":"chunked","server":"Cowboy","x-android-response-source":"NETWORK
415","x-android-selected-protocol":"http/1.1","expires":"0","x-xss-protection":"1;
mode=block"},"error":"{\"timestamp\":1512686795600,\"status\":415,\"error\":\"Unsupported Media
Type\",\"exception\":\"org.springframework.web.HttpMediaTypeNotSupportedException\",\"message\":\"Content
type 'application/x-www-form-urlencoded;charset=UTF-8' not supported\",\"path\":\"/api/users\"}"}]}
Check please in the error logs, the headers object. How can I leave only 'content-type': 'application/json'?
Thank you very much!