I have written a node.js proxy server ( its here on github )
The problem is that the connect.bodyParser doesn't work very well.
For this probject I've written my own bodyParser (see the file 'server'), but now I was testing again with connect.bodyParser. In short, I have now something like:
app.use(connect.bodyParser())
.use(connect.query())
.use(serveFromDB)
.use(actAsProxyServer)
.use(cacheContent)
.use(function(err, req, res, next) {
console.log("ERROR: " + JSON.stringify(err)) ;
console.log("URL=" + req.url) ;
console.dir(req.headers) ;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(err));
}) ;
Here is output from the error function:
ERROR: {"status":400}
URL=/Client/rest/cache/Clients/user123/X7X1
{ host: 'localhost:8000',
connection: 'keep-alive',
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'content-type': 'application/json; charset=utf-8',
accept: 'application/json, text/javascript, */*; q=0.01',
referer: 'http://localhost:8000/Client/index.jsp?cache=true',
'accept-encoding': 'gzip,deflate,sdch',
'accept-language': 'en-US,en;q=0.8',
'accept-charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
cookie: 'JSESSIONID=d1cbd411e30bcfb759e29585ee23' }
The only thing this GET request does is calling that url (without any parameters)
Any suggestions why the bodyParser throws an error on this GET request ?
Cheers
UPDATE: I found the code of bodyParser here. In json.js it finaly throws the error because its trying to turn an empty string (because there is no body) into json. I though bodyParser is only for POST request!!
UPDATE1: found the problem: https://github.com/documentcloud/backbone/pull/267 I think I have a content-type in my GET request
Have a look at B2MSolutions / gzip-bodyparser
Related
I'm facing an issue trying to connect an flutter application with my nodejs backend with express-session. In postman the response header includes a "Set-Cookie"-Header, but the flutter headers with http.post(...) do not: headers: {content-length: 113, content-type: application/json; charset=utf-8}.
I need a cookie to keep the authenticated session with passport. Any ideas how to fix it?
Flutter headers:
host: '127.0.0.1:3000', connection: 'keep-alive', 'content-length': '57', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36', 'content-type': 'application/json; charset=utf-8', accept: '*/*', origin: 'http://localhost:51879', 'sec-fetch-site': 'cross-site', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', referer: 'http://localhost:51879/', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7'
Postman Headers: 'content-type': 'application/json', accept: '*/*', 'postman-token': '7c79280d-****-****-a985-c01395e50e08', host: 'localhost:3000', 'accept-encoding': 'gzip, deflate, br', connection: 'keep-alive', 'content-length': '66'
Recommend you to use dio library for HTTP calls.
import 'package:dio/dio.dart';
class ApiProvider {
Dio _dio;
String aToken = '';
final BaseOptions options = new BaseOptions(
// base url to backend server
baseUrl: 'http://a.b.c.d:port/',
connectTimeout: 15000,
receiveTimeout: 13000,
);
static final ApiProvider _instance = ApiProvider._internal();
factory ApiProvider() => _instance;
ApiProvider._internal() {
_dio = Dio(options);
_dio.interceptors.add(InterceptorsWrapper(
onRequest:(Options options) async {
// to prevent other request enter this interceptor,
// use a new Dio(to avoid dead lock) instance to request token.
_dio.interceptors.requestLock.lock();
// set the cookie to headers
options.headers["cookie"] = aToken;
_dio.interceptors.requestLock.unlock();
return options; // continue
}
));
}
Future login() async {
final request = {
"userName": "",
"password": "",
"token": ""
};
final response = await _dio.post('/login', data: request, options: Options(
followRedirects: false,
validateStatus: (status) { return status < 500; }
));
//get cooking from response
final cookies = response.headers.map['set-cookie'];
if (cookies.isNotEmpty && cookies.length == 2) {
// it depends on how your server sending cookie
aToken = cookies[1].split(';')[0];
}
}
/// if we call this function without cookie then it will throw 500 err.
Future getSomething() async {
final response = await _dio.post('/something');
}
}
I have set up an angular 8 app, that connects to an express API.
I'm running it locally, to test.
My front end app connects to http://localhost:4200/ and backend to http://localhost:3000/
I've set up an express route to connect to https://api.podbean.com/v1/podcasts?access_token=baee9cb65384a814e704adc626dc969bb019f84d
which works fine, returning all podcasts
But the debugToken endpoint never works via the express route, if I use https://api.podbean.com/v1/oauth/debugToken?access_token=baee9cb65384a814e704adc626dc969bb019f84d
Using postman with basic auth clientId = '7faf9a7ad38a01c7d900c' client_secret = 'a7a3825f02be39c57ff44' it works ok, but never when connecting via localhost
I'm using GET
It must be connecting because I get an object returned, although it's an error
In Angular:
debug() {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Basic ' + btoa('7faf9a7ad38a01c7d900c:a7a3825f02be39c57ff44')
})
};
console.log(httpOptions);
return this.http.get(`${this.configUrl}/debug/`, httpOptions);
}
Express:
router.get('/debug', function (req, res, next) {
var options = {
url: `https://api.podbean.com/v1/oauth/debugToken?access_token=${accessToken}`
}
request(options, function (err, response, body) {
console.log( req.headers);
if(err){
return res.status(500).json({
title: 'An error has occured',
error: err
})
}
res.json(JSON.parse(body));
next();
})
});
When I log the request headers in the express/node side
{host: 'localhost:3000',
connection: 'keep-alive',
pragma: 'no-cache',
'cache-control': 'no-cache',
'sec-fetch-mode': 'cors',
origin: 'http://localhost:4200',
authorization: 'Basic N2ZhZjlhN2FkMzhhMDFjN2Q5MDBjOmE3YTM4MjVmMDJiZTM5YzU3ZmY0NA==',
'content-type': 'application/json',
accept: 'application/json, text/plain, */*',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',
dnt: '1',
'sec-fetch-site': 'same-site',
referer: 'http://localhost:4200/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-GB,en;q=0.9,en-US;q=0.8,it;q=0.7,es;q=0.6' }
Returned object:
{"error":"invalid_token","error_description":""}
Which tells me I'm connecting, just not correctly
Looks like you just confused endpoints. You are sending basic auth from Angular page to your Express endpoint,
which doesn't make much sense, because it's https://api.podbean.com who requires authorization, not your Express server.
Try adding basic auth credentials to the request which goes from your Express server to api.podbean.com
router.get('/debug', function (req, res, next) {
var options = {
url: `https://api.podbean.com/v1/oauth/debugToken?access_token=${accessToken}`,
headers: {
'Authorization': 'Basic ' + new Buffer("7faf9a7ad38a01c7d900c:a7a3825f02be39c57ff44").toString('base64')
}
}
request(options, function (err, response, body) {
...
I need to access axios header authorization token in server side(Node), showing undefined. Please help..
Client side(React) request:
var config = {
headers: {
'cache-control':'no-cache',
'content-type': 'application/x-www-form-urlencoded',
'authorization' :'bearer '+Auth.getToken()
}
};
axios.get(ApiConfig.API_BASE+'api/admin/profile/', config).then(function(response) {
this.setState({status:'success', profile: response.data.data});
}).catch(function(response) {
console.log(response);
});
Server side(Node):
module.exports = (req, res, next) => {
console.log(req.headers.authorization);
if(!req.headers.authorization) {
return res.status(401).end();
}
};
Log showing undefined. I also console the entire header, but their output is:
{ host: 'localhost:8027',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'accept-language': 'en-US,en;q=0.5',
'accept-encoding': 'gzip, deflate',
'access-control-request-method': 'GET',
'access-control-request-headers': 'authorization,cache-control',
origin: 'http://localhost:3001',
connection: 'keep-alive' }
How do I retrieve the authorization token value?
Thank you.
I'm assuming you are using express. If so, instead of getting the header value as req.headers.authorization, try req.get('authorization').
http://expressjs.com/en/api.html#req.get
If you are making a cross-origin HTTP request, please make sure CORS has been enabled in your server. If you are using express cors middleware can be used.
I guess your problem here is that since CORS has not been enabled, your server will receive a OPTIONS request first, so the entire header you console is from the OPTIONS request not the GET request as you desired. You can use console.log(req.method) to verify. BTW req.headers.authorization is ok to receive the header.
I am using the request npm module.I want to retrieve an image from a url. The request.get(url) function is returning me a '400 Bad Request', whereas the image is accessible from the browser.
The url i am hitting is : http://indiatribune.com/wp-content/uploads/2017/09/health.jpg
You could try to add some headers:
const request = require('request');
request.get({
url: 'http://indiatribune.com/wp-content/uploads/2017/09/health.jpg',
headers: {
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-GB,en;q=0.8,en-US;q=0.6,hu;q=0.4',
'Cache-Control': 'max-age=0',
Connection: 'keep-alive',
Host: 'indiatribune.com',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
},
}, (err, response, data) => {
console.log(response, data);
});
The User-Agent seems to be enough.
Use download module . It's pretty simple.
const fs = require('fs');
const download = require('download');
download('http://indiatribune.com/wp-content/uploads/2017/09/health.jpg').pipe(fs.createWriteStream('foo.jpg'));
Tried multiple approaches to send custom-headers via Aurelia-http-client and Aurelia-Fetch-client to pass Headers in the get/post requests that I am making, but in the actual request, the headers are not being passed
approach 1
var client = new HttpClient()
client.createRequest('/api/information/save')
.asPost()
.withBaseUrl('http://10.0.0.13:3000')
.withHeader("X-auth-code", "abc")
.send()
approach 2
var client = new HttpClient()
.configure(x => {
x.withBaseUrl('http://10.0.0.13:3000');
x.withCredentials(true);
x.withHeader('Content-Type', 'application/json; charset=utf-8');
x.withHeader('x-client-code', 'abc');
});
Approach 3
this.http.configure(config => {
config
.withDefaults({
credentials: 'same-origin',
headers: {
"Content-Type": "application/json",
"x-client-code": "abc",
}
})
.useStandardConfiguration()
.withInterceptor({
request(request) {
request.headers.append("x-client-code","abc");
console.log(`${request.headers}`);
return request; // you can return a modified Request, or you can short-circuit the request by returning a Response
},
response(response) {
console.log(`Received ${response.status} ${response.url}`);
return response; // you can return a modified Response
}
});
})
But all of them lead to the same error
{ host: '10.0.0.13:3000',
connection: 'keep-alive',
'access-control-request-method': 'POST',
origin: 'http://localhost:9000',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36',
'access-control-request-headers': 'content-type',
accept: '*/*',
referer: 'http://localhost:9000/',
'accept-encoding': 'gzip, deflate',
'accept-language': 'en-GB,en-US;q=0.8,en;q=0.6' }
At the end we are unbable to pass the headers.
it's a security against cross-site scripting (and it's super annoying) #see : Cors Access-Control-Allow-Headers wildcard being ignored?