How to get “HTTP_REFERER” with koa in nodejs? - javascript

How can i get the referrer from the request object? The variable this.request.headers['referer'] was empty.

If your page was referred by another page, the referer will be accessable through this.headers.referer.
If the page was not refered by another page (was loaded directly), this.headers.referer will be undefined.
This demo code:
'use strict'
const Koa = require('koa')
let app = new Koa()
app.use(function * () {
console.log(this.headers)
})
app.listen(8888)
Yielded this when referred by another page:
{ host: 'localhost:8888',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.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',
referer: 'http://localhost:1111/',
connection: 'keep-alive' }
And this when loaded directly:
{ host: 'localhost:8888',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.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',
connection: 'keep-alive' }

For newer koa versions - I currently use 2.5.1 - a warning is generated because of the generator function *(), so here's a newer example with ES6 syntax
const Koa = require('koa')
const app = new Koa()
app
.use(async (ctx) => console.log(ctx.request.headers))
app.listen(8888)
Output should be the same as described by #JoshWillik except the warning
Edit:
gif add that shows that it works
and a sample repository to try out

Related

Axios interceptor does not set Authorization header on mobile device

I am using an Axios interceptor in my React application to add an Authorization header. This works fine on desktop browsers (Chrome), however on mobile browsers (iOS, Safari and Chrome) the Authorization header is not set.
I am using Axios (0.23.0).
Here is the Axios code:
// api.js
export const ProtectedAPI = axios.create({
baseURL: `${REACT_APP_API_URL}/`,
});
ProtectedAPI.interceptors.request.use(
(config) => {
const currentUser = JSON.parse(window.localStorage.getItem("current_user"));
config.headers = {
Authorization: "Bearer " + currentUser.accessToken,
};
return config;
},
(error) => {
return Promise.reject(error);
}
);
Here is how it is called in my component:
// myComponent/index.js
const accountRes = await ProtectedAPI.get(
"account/get_account"
);
These are the headers received by the API from mobile browsers:
{
Connection: "upgrade",
Host: "<MY_API_ENDPOINT>",
"X-Real-Ip": "<IP_REMOVED_BY_ME>",
"X-Forwarded-For": "<IP_REMOVED_BY_ME>",
Accept: "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
Origin: "<MY_ORIGIN>",
"User-Agent":
"Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/94.0.4606.76 Mobile/15E148 Safari/604.1",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https",
};
These are the headers received by the API from desktop browsers:
{
Connection: "upgrade",
Host: "<MY_API_ENDPOINT>",
"X-Real-Ip": "<IP_REMOVED_BY_ME>",
"X-Forwarded-For": "<IP_REMOVED_BY_ME>",
Accept: "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
Authorization:
"Bearer <MY_ACCESS_TOKEN>",
Dnt: "1",
Origin: "<MY_ORIGIN>",
"Sec-Ch-Ua":
'"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https",
};
As you can see, the desktop browser request includes the Authorization header and token, while the mobile request does not. Is there something different about the way Axios interceptors work on mobile browsers?

axios does not return the full data

axios.get(downloadUrl, Object.assign({}, this.tokens[token_nr].config, {responseType: stream}))
.then((response) => {
console.log("HEADERS", response.headers)
console.log(typeof response.data, "RESPONSE LENGTH", response.data.length)
const decryptedBuffer = encryptionService.decrypt(Buffer.from(response.data), infos);
resolve(decryptedBuffer);
})
This axios request should give the data of a mp3 file. I previously had it via the request package which gives a binary Buffer (using the encoding: null option) and I can use it in the encryptionService.decrypt() function.
In the response.headers I can see it gives the same content-length as it would with the request package. But when I print the length of response.data it's shorter. I tried both ArrayBuffer and stream as my ResponseType. Also leaving the ResponseType option out does not help. What should I do to get the full content.
Some logs: (not all headers)
HEADERS {
'accept-ranges': 'bytes',
'cache-control': 'public',
'content-type': 'audio/mpeg',
'content-length': '14175084',
connection: 'close'
}
string RESPONSE LENGTH 13495410
CONFIG HEADERS {
headers: {
Accept: 'application/json, text/plain, */*',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36',
'cache-control': 'max-age=0',
'accept-language': 'en-US,en;q=0.9,en-US;q=0.8,en;q=0.7',
'accept-charset': 'utf-8,ISO-8859-1;q=0.8,*;q=0.7',
cookie: 'arl=XXXX',
Connection: 'keep-alive',
'Keep-Alive': 'timeout=1500, max=100',
'Content-Type': 'text/plain;charset=UTF-8'
},
}
When creating request try passing following headers Connection, Keep-Alive. Sometimes it close the connection before fully receiving the response
var axioRequest = await axios.create({
baseURL: url,
headers: {
Connection: 'keep-alive',
'Keep-Alive': 'timeout=1500, max=100'
}
});
It was resolved with this answer:
https://disjoint.ca/til/2017/09/20/how-to-download-a-binary-file-using-axios/
I missed the Content-Type header and the {ResponseType: 'arraybuffer'}

Creating a custom Header in a Chrome Extension fails [duplicate]

This question already has answers here:
Trying to use fetch and pass in mode: no-cors
(9 answers)
Closed 3 years ago.
I try to create a Header for a following fetch() like this
var myheaders = new Headers(
{ "Accept": "application/json",
"Content-Type": "application/json; charset=UTF-8"
});
let b = JSON.stringify ({ "cmd2" : "ytdl", "url" : "x"});
let params =
{ headers : myheaders,
body : b,
method : "POST",
mode : "no-cors"
};
let response = await fetch("http://127.0.0.1:5000/ytdl",params);
....
If I print the headers in the receiving Server (Flask) I get:
Host: 127.0.0.1:5000
Connection: keep-alive
Content-Length: 67
Accept: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: no-cors
Content-Type: text/plain;charset=UTF-8
Origin: chrome-extension://mnihgjnpmkpgeichhdfhejagbefjpnnb
Sec-Fetch-Site: cross-site
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Any Idea, what I´m doing wrong?
I didn't understand what is the reason but when you call without mode: 'no-cors' content type is:
let params = {
headers : myheaders,
body : b,
method : "POST",
mode : "cors"
};
response = await fetch("http://127.0.0.1:5000/", params);
The output of the flask request.headers:
...
Accept: application/json
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: cors
Content-Type: application/json; charset=UTF-8
...

Nodejs request issue with especific endpoint (Client network socket disconnected)

This is my entire code
const rp = require('request-promise');
(async () => {
const headers = {
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
Host: 'www.receita.fazenda.gov.br',
Pragma: 'no-cache',
'Upgrade-Insecure-Requests': 1,
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:64.0) Gecko/20100101 Firefox/64.0',
};
const jar = rp.jar();
try {
const firstAccess = await rp.get('https://www.receita.fazenda.gov.br/Aplicacoes/SSL/ATCTA/CPF/ConsultaSituacao/ConsultaPublica.asp', {
headers,
gzip: true,
simple: false,
strictSSL: false,
jar,
});
console.log(firstAccess);
} catch (e) {
console.log(e);
}
})();
When i run my code i receive this error:
UnhandledPromiseRejectionWarning: RequestError: Error: Client network
socket disconnected before secure TLS connection was established
The url works in the browser, but I can not access through nodeJS, apparently it's some problem with the https certificate
Is there any way to ignore the error and access it?
You need to move your call inside a try catch block to handle the promise rejection in case the call fails:
...
try {
const firstAccess = await rp.get(...)
} catch (e) {
console.log(e)
}
...
My problem was resolved after restarting/changing the network connection. The issue is with the network most of the time.

Client side(Jquery&Angular) can't send request with x-access-token headers

I followed this article build a web api with token in Node.js:
var token = req.body.token || req.query.token || req.headers['x-access-token'];
if (token) {console.log("passed!");}
else
{console.log("No token provided.");}
I tested with Postman and tried with http://localhost:3000?token=eyJ0eXAiO
all work fine, but when call API in client side:
app.controller('myCtrl', function($scope, $http, $cookies) {
var apikey=$cookies.get('apikey');
$http({url: 'http://localhost:3000/', method: 'GET', headers: {'x-access-token': apikey}})
.success(function (data) {
console.log(data);
}).error(function(error){console.log(error);});
and jquery call:
jQuery.ajax( {
url: 'http://localhost:3000/',
type: 'GET',
beforeSend : function( xhr ) {
xhr.setRequestHeader( 'x-access-token', 'eyJ0eXAi');
},
success: function( response ) {
console.log(response);
},
error : function(error) {
console.log(error);
}
} );
What every Angular or jquery did not work and return "No token provided."
what did I miss? Please help me.
Here is headers from req.headers
Angular.JS
{ host: 'localhost:3000',
connection: 'keep-alive',
'cache-control': 'max-age=0',
'access-control-request-method': 'GET',
origin: 'localhost:3001',
'user-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/43.0.2357.132 Safari/537.36',
'access-control-request-headers': 'accept, max-age, x-access-token',
accept: '/',
referer: 'localhost:3001',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-CA,en;q=0.8,en-US;q=0.6,zh-CN;q=0.4,zh;q=0.2,zh-TW;q=0.
2' }
No token provided.
Postman
{ host: 'localhost:3000',
connection: 'keep-alive',
csp: 'active',
'cache-control': 'no-cache',
'x-access-token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoibGF3cmVuY2
UiLCJwYXNzd29yZCI6InNreTIwMDAiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNDM2Mzc0NTYzLCJleHAiOj
E0MzY0NjA5NjN9.OycP6xdUlG3vLyZHcj4rLjyYKE1GnlWc3h-f0r1ZpZ0',
'user-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/43.0.2357.132 Safari/537.36',
'postman-token': 'ab2a26e3-f6a1-09e0-c21a-85e3cef0aff5',
accept: '/',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-CA,en;q=0.8,en-US;q=0.6,zh-CN;q=0.4,zh;q=0.2,zh-TW;q=0.
2' }
passed!
It turned out this is a Chrome issue, have to run Chrome with --disable-web-security then the headers request works.
CORS, Cordova, AngularJs $http and file:// confusion

Categories

Resources