NodeJS: header authorization missing from redirect using res.writeHead - node.js

I want to redirect an HTTP request to another NodeJS server.
I am using the res.writeHead in order to redirect the request.
Code alternative 1:
let headers = Object.assign({},req.headers)
await Object.entries(headers).forEach(async ([header,value]) => {
await res.setHeader(header,value)
})
await res.setHeader('Location',ENV_CONFIG.ENV_US_URL + req.url)
res.writeHead( 307 );
res.end();
code alternative 2:
let headers = Object.assign({},req.headers)
headers['Location'] = ENV_CONFIG.ENV_US_URL + req.url
res.writeHead( 307, {...headers} );
res.end();
code alternative 3:
let headers = Object.assign({},req.headers)
res.writeHead( 307, {'Location': ENV_CONFIG.ENV_US_URL + req.url,...headers} );
res.end();
The three alternatives deliver the same results.
The res headers do include the authorization header before it sent to the other NodeJS server.
When the "new" request arrives to the other NodeJS server, the authorization header is missing
The request header DO contain the authorization header.
why would the authorization header fall there?
BTW. I tried to set the value of the authorization header in some custom header, it went missing as well.

Headers like auth headers and other custom headers are NOT preserved by the browser when you do a redirect. The browser forms a new request to the location you specified in the redirect response and builds that new request with default headers, not with the headers from your redirect response. It is as if the user typed the redirected URL into the browser URL bar and the browser created a new, default request to that new URL.
You will need to pass information to the redirected request either via the URL path, via query parameters or via a cookie. Query parameters and the URL path will always be present on the redirected request and cookies will be present if the cookie is set on the domain of the redirected target.
When the "new" request arrives to the other NodeJS server, the authorization header is missing
Headers are not preserved when redirecting the browser. The browser creates a new request with default headers to the location specified in the redirect. Any information you want to communicate to the new target must be either in the redirect URL (path or query parameters) or in a cookie that is set on the target domain.

Related

How to add readable text to URL with NodeJS Express?

I have links that looks like this on my website:
https://website.com/view?id=8d23iva
When users go to the link, I want the URL to change based on information related the id parameter like this:
https://website.com/view?id=8d23iva/amazing-book-title
I have been messing around changing the req and res object data before the user is sent to the page similarly to this.
app.get('/view', (req, res, next) => {
res.baseUrl = "/test";
req.url = req.url + '/test';
req.originalUrl = req.originalUrl + '/test';
next();
});
As an HTTP server, the primary way you can influence the client (i.e the users browser) is with your HTTP response. To change their location you can return a redirection response.
A redirection response is any HTTP response with a 3XX status code and a Location header set to the new destination. In express you can use res.redirect(/*your location here*/) to send a redirection response. For more information about different types of redirects check out this MDN article.
As a side note, you could also consider making the change to the location using javascript on the client once the page is loaded. Though this will depend on other factors. You could investigate the History api for this.

How can I get the authorization from the site using requests Python

there is a site I want to send some requests to, but it asks me the authorization when sending a post-type request.
This is the form of authorization:
The problem is that it is inside the Request Headers, and when I do this process:
r = requests.get("https://www.examplesite.com")
print(r.headers)
The Response Headers data is returned, but I want to get the authorization from the request headers ..
how it would be ?
this response headers ..
and this request heades, I want to get it..
If the authorization is in the request header, you need to set it when you are forming the request, before you send it to the intended host.
import requests
headers = { "authorization": "random-gibberish-that-is-the-auth" }
request = requests.post("https://www.examplesite.com", headers=headers)
This means, you will need to have an authorization key that you can assign to the authorization header prior to making your request.

Redirect in Flask - pass a custom header in the request to target

TLDR; How do I set a custom HTTP request header in redirect?
Below code redirects to an external service but fails to pass 'Authorization' request header to target. I can see the header in response before redirect happens - can it be forwarded somehow?
#app.route('/external_page')
def external_page():
if not request.cookies.get('id_token'):
return flask.redirect(flask.url_for('login',_external=True,_scheme=SCHEME))
response = flask.redirect(flask.url_for('https://external_service_url/v1/ui'))
response.headers['Authorization'] = 'token_id'
return response
Answer:
It's not possible, in HTTP and not in any framework.
The only way for a site to instruct a browser to issue an HTTP request
with a custom header is to use Javascript and the XMLHttpRequest
object. And it needs CORS implemented on the target server to allow
such ajax requests.
Source: Redirect to page and send custom HTTP headers
It's not possible
See Redirect to page and send custom HTTP headers
The only way for a site to instruct a browser to issue an HTTP request
with a custom header is to use Javascript and the XMLHttpRequest
object. And it needs CORS implemented on the target server to allow
such ajax requests.

Why is my header not being set on redirect?

I have an express route. I set a header and a cookie and then I redirect.
router.get("/callback", async (req, res) => {
res.cookie("token", token, {
maxAge: COOKIE_EXPIRATION_MILLISECONDS
});
res.header("TEST", "HEADER");
res.redirect("/test");
});
When I hit /test, token is set and available. I do not have a header named TEST. Why do I not have the header? How do I pass the header through the redirect?
Your header is likely being sent with the response, but you won't see that header when the browser actually follows the redirect and then requests the new URL. Browsers don't do that. Remember, when you do res.redirect(), it sends a response with a 302 status and a location header. The browser sees that 302 and reads the location header and then makes a new browser request to your server for the redirected location. Headers from the previous response are NOT added to the new request for the redirected location.
The usual ways to pass data like this to a redirected requests are:
Put it in the query string for the redirected URL as a parameter. Your server will then see that query string when the redirected requests comes in.
Set a cookie. Your server can then look at the cookie when the redirected request comes in.
Set data in a server-side session object that can be accessed on the next request. Your server can then look at the session when the redirected request comes in.
Only the first option above (query parameter) is entirely safe because the others can get confused about which request the data belongs to if there are other requests coming in from that same user.

Does any browser implementation uses full url path in Origin header in an ajax request?

I'm talking about a CORS preflight HTTP request by the OPTIONS method which is sent by default by the browser before the actual request. In that request is it possible to make Orgin header to include the full url path?
OPTIONS / HTTP/1.1
Host: example.com
Origin: http://www.example.com/blah
I want my page to send full url in Origin header. Is there any way to trick the browser to do so?
you can always pass this value on the ajax parameters using something like:
$.ajax(url, {
fullOrigin: window.location.href
}
)
like #Robby Cornelisse said - most servers will hold REFERER server variable with this value.
The browser will send a REFERER header containing the full URL with your AJAX request.
In the screenshot below, I just used the console to send an AJAX request from this page. Notice the Referer header.
No, it's not possible. Origin is a scheme, domain and port parts of an URI by definition.
One option is to send current document URI to server using query part of request URI. You can use code below to change URI of every cross origin request on your page:
window.addLocation = function( uri ) {
var parser = document.createElement('a');
parser.href = uri;
var and = parser.search ? "&" : "";
parser.search = parser.search + and + "madeBy=" + window.location;
return parser.href;
};
var xhr = new XMLHttpRequest();
xhr.open( "GET", window.addLocation( originalUri ), true );
Note that current page URI may contain sensitive information, and that browser identifies HTTP Cache entries by URI including query.
For more information check:
Origin header page on MDN
Referer header section in HTTP 1.1 specification
URL Parsing gist by jlong
HTTP access control (CORS) page on MDN

Resources