How to remove cookie param in request header for a post request in angular 6 - angular6

When sending a post request cookie param is getting set in request header.
Is there any way to stop sending cookie param in api request header for a particular api call in angular interceptor

http module by default does not set the cookie params. When you get the response, http module discards the cookie and does not add it in the follow up requests. So you have add it manually:
checkAuth() {
// if we did not add { withCredentials: true }, response would be false becasue, cookies wont be attached
return this.http.get<SignedinResponse>(this.rootUrl + '/signedin',{withCredentials:true}).pipe(
tap(({ authenticated }) => {
// console.log('response from /signedin', res);
})
);
}
you have to add {withCredentials:true} this to each request manually. instead we write interceptor, to modify the req obj and add the cookie by default.

Related

Can I send my cookies from domainA to domainB in header cookie

I currently have an client hosted on domainA. It reaches out to an endpoint on domainB and I would like to include the cookies from domainA in that request to domainB.
Right now the only cookies that are sent are cookies generated on my machine for domainB.
Is there some sort of security header I can set on the client that allows the sharing of its cookies with domainB or is this a security violation. I can always pass it through as a payload in the body, but it would be nicer if I could just use the withCredentials param to allow it.
// Request
const response = await axios({
method: method as Method,
baseURL,
endpoint,
data,
params,
headers: {
'content-type': 'application/json',
...authorization
},
withCredentials: true // allow sharing of cookies
});
Manually trying to set the cookie header results in the browser complaining Refused to set unsafe header "Cookie"
I think the solution involves the Access-Control-Allow-Headers header on the response headers, but I am unsure

chrome.webRequest.onBeforeSendHeaders, uses HTTP Options method instead of GET and POST from the redirected method

//PUT HEADERS IS REDIRECTED REQUEST
chrome.webRequest.onBeforeSendHeaders.addListener(
info =>{
info.method = "GET"
//alert('onBeforeSendHeaders redirect ' +info.method);
let key = info.url.replace(replace, 'key-');
let currentHeaders = info.requestHeaders;
let requestHeaders = map.get(key)
requestHeaders.push(...currentHeaders);
requestHeaders.push({'name':'Access-Control-Allow-Origin', 'value':'*'})
requestHeaders.push({'name':'ISISessionid', 'value':'null'})
return {requestHeaders}
},
{urls : [`${replace}/*`]},
['blocking','requestHeaders','extraHeaders'])
In this I am trying to insert some extra headers in a redirected GET request. The headers are added successfully, but the request method changes to 'OPTIONS' every time.
I tried to force the method, but it also does not works.

How to make a video stream http GET request to img html tag with axios?

I have a Django 2.1 backend that have a video stream endpoint and a Vue-Cli3 as my frontend.
The videostream endpoint in my backend is a GET request. To have the streaming working in my client side all i needed was to add:
<img :src="$store.state.domain + 'cameras/video/' + camera.properties.name + '/'" width="240" alt="Camera live Stream">
This works fine but now i have to protect my back-end route for authenticated users only. For this i just need to add an authentication token in the request header.
The problem is, according to Set custom header for the request made from <img/> tag , an img tag doesn't accept header parameters.
So now I'm trying to build a request using axios library and then stream the request result to my HTML img tag.
my Vue method code so far:
loadStream(){
const vm = this
let accessToken = vm.$store.getters.getAccessToken
let streamURL = `${vm.$store.state.domain}/cameras/video/${vm.camera.properties.name}/`
axios.get(streamURL, {headers: {"Authorization": `Bearer ${accessToken}`},
responseType: 'stream',
adapter: httpAdapter}
).then( response =>{
console.log(`success:${response.data}`)
let imgTag = document.createElement('img')
imgTag.src = URL.createObjectURL(response)
imgTag.classList.add('video-modal', 'popup-video')
imgTag.alt = `Camera ${camera.properties.name} liveStream`
imgTag.setAttribute("crossorigin", '')
let streamDiv = document.getElementById('livestream-img')
streamDiv.appendChild(imgTag)
}).catch( error => {
console.log(`error:${response.data}`)
let imgTag = document.createElement('img')
imgTag.alt = `Camera ${camera.properties.name} liveStream`
let streamDiv = document.getElementById('livestream-img')
streamDiv.appendChild(imgTag)
})
}
All i get is this warning:
Warning: The provided value 'stream' is not a valid enum value of type XMLHttpRequestResponseType.
Also my request never ends. Promise will never hit .then() or .catch() because it's streaming. Seems like responseType isn't working properly. am i missing something?
This is my django backend endpoint:
class CameraVideoStreamingView(APIView):
def get(self, request, name):
cam = Camera.objects.get(name=name)
return StreamingHttpResponse(cam.serve_web_stream(),
content_type="multipart/x-mixed-replace;boundary=frame")
I would recommend sending some sort of auth token in the video's query params, and to handle this, implementing a custom Token Authentication Class which gets the token from a query param rather than the headers. You'd then have to update the authentication_classes property of your view with your new authentication class.

Node-red - Posting data to influxdb via http

Im trying to post data to an Influxdb via Node-red.
Via CURL i can post this:
curl -i -XPOST 'http://localhost:8086/write?db=waterlevel' --data-binary 'vattenstand,lake=siljan,region=dalarna value=160.80'
and it puts data to InfluxDb.
When I try to post via Node-red and an HTTP request I get the error:
{"error":"unable to parse '{\"url\":\"http://192.168.1.116:8086/write?db=waterlevel\",\"method\":\"POST\",\"body\":\"vattenstand,lake=siljan,region=dalarna value=160.80\",}': missing tag value"}
I use this code in a function in Node-red and pass it to the HTTP request:
var dataString = 'vattenstand,lake=siljan,region=dalarna value=160.80';
msg.payload = {
'url': 'http://192.168.1.116:8086/write?db=waterlevel',
'method': 'POST',
'body': dataString,
};
msg.headers = {
Accept: "application/json"
};
return msg;
The sidebar help for the node details the msg properties you should be setting to configure the node.
You are passing in URL, method and body as properties of msg.payload. That is not correct.
They should be set as msg.url, msg.method for the first two, and msg.payload should be the body of the request.
In this instance, you have already configured the node with a URL and method directly, so there's no need to pass them in with the message. In fact, as you have configured the URL in the node you will find you cannot override it with msg.url. if you want to set the URL with each message, you must leave the node's URL field blank in the editor.
You may also need to set the content-type header.
Assuming you are happy to leave the URL and method hard coded in the node, you function should be something like:
msg.payload = 'vattenstand,lake=siljan,region=dalarna value=160.80';
msg.headers = {
Accept: "application/json"
};
msg.headers['Content-type'] = 'application/x-www-form-urlencoded';
return msg;
Why don't you use the spezial influxdb node?
https://flows.nodered.org/node/node-red-contrib-influxdb
Advantage: The http header need not be created. You can reuse the defined connection for other data.

Allow Access-Control-Allow-Origin header using HTML5 fetch API

I am using HTML5 fetch API.
var request = new Request('https://davidwalsh.name/demo/arsenal.json');
fetch(request).then(function(response) {
// Convert to JSON
return response.json();
}).then(function(j) {
// Yay, `j` is a JavaScript object
console.log(JSON.stringify(j));
}).catch(function(error) {
console.log('Request failed', error)
});
I am able to use normal json but unable to fetch the data of above api url.
It throws error:
Fetch API cannot load https://davidwalsh.name/demo/arsenal.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Like epascarello said, the server that hosts the resource needs to have CORS enabled. What you can do on the client side (and probably what you are thinking of) is set the mode of fetch to CORS (although this is the default setting I believe):
fetch(request, {mode: 'cors'});
However this still requires the server to enable CORS as well, and allow your domain to request the resource.
Check out the CORS documentation, and this awesome Udacity video explaining the Same Origin Policy.
You can also use no-cors mode on the client side, but this will just give you an opaque response (you can't read the body, but the response can still be cached by a service worker or consumed by some API's, like <img>):
fetch(request, {mode: 'no-cors'})
.then(function(response) {
console.log(response);
}).catch(function(error) {
console.log('Request failed', error)
});
This worked for me :
npm install -g local-cors-proxy
API endpoint that we want to request that has CORS issues:
https://www.yourdomain.com/test/list
Start Proxy:
lcp --proxyUrl https://www.yourdomain.com
Proxy Active
Proxy Url: http://www.yourdomain.com:28080
Proxy Partial: proxy
PORT: 8010
Then in your client code, new API endpoint:
http://localhost:8010/proxy/test/list
End result will be a request to https://www.yourdomain.ie/test/list without the CORS issues!
Solution to resolve issue in Local env's
I had my front-end code running in http://localhost:3000 and my API(Backend code) running at http://localhost:5000
Was using fetch API to call the API. Initially, it was throwing "cors" error.
Then added this below code in my Backend API code, allowing origin and header from anywhere.
let allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Headers', "*");
next();
}
app.use(allowCrossDomain);
However you must restrict origins in case of other environments like stage, prod.
Strictly NO for higher environments.
I know this is an older post, but I found what worked for me to fix this error was using the IP address of my server instead of using the domain name within my fetch request.
So for example:
#(original) var request = new Request('https://davidwalsh.name/demo/arsenal.json');
#use IP instead
var request = new Request('https://0.0.0.0/demo/arsenal.json');
fetch(request).then(function(response) {
// Convert to JSON
return response.json();
}).then(function(j) {
// Yay, `j` is a JavaScript object
console.log(JSON.stringify(j));
}).catch(function(error) {
console.log('Request failed', error)
});
You need to set cors header on server side where you are requesting data from.
For example if your backend server is in Ruby on rails, use following code before sending back response. Same headers should be set for any backend server.
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
If you are use nginx try this
#Control-Allow-Origin access
# Authorization headers aren't passed in CORS preflight (OPTIONS) calls. Always return a 200 for options.
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Origin "https://URL-WHERE-ORIGIN-FROM-HERE " always;
add_header Access-Control-Allow-Methods "GET,OPTIONS" always;
add_header Access-Control-Allow-Headers "x-csrf-token,authorization,content-type,accept,origin,x-requested-with,access-control-allow-origin" always;
if ($request_method = OPTIONS ) {
return 200;
}
Look at https://expressjs.com/en/resources/middleware/cors.html
You have to use cors.
Install:
$ npm install cors
const cors = require('cors');
app.use(cors());
You have to put this code in your node server.