Confusion with cookies - javascript

I'm trying to establish a session using AngularJS, as follows:
var login = function (email, pw) {
$http.post('http://some_api/api/v1/users/sign_in', {'email': email, 'password': pw}
).
success(function (data, status, headers, config) {
alert('success');
console.log(status, headers());
SessionService.isLogged = true,
SessionService.name = data.name,
SessionService.id = data.id,
SessionService.email = email,
SessionService.password = pw,
SessionService.coverUrl = data.coverUrl,
SessionService.imageUrl = data.imageUrl;
// TODO Also store venue id associated to user if applicable
SessionService.venueId;
//TODO route to whatever page we came from in the case that user is being asked to re-authenticate
$location.url('/summary');
}
).
error(function(data, status, headers, config){
SessionService.destroy();
alert('login failure');
}
);
However, when the request response comes back from the API, I only get the following headers by using the $cookies service:
cache-control: "max-age=0, private, must-revalidate"
content-type: "application/json; charset=utf-8"
However, I know the cookie is sent back from the server because Chrome sends it back in the Developer Tools as a populated Set-Cookie header. I read in another question that AngularJS cannot access the Set-Cookie header because the $http service because the inherent spec of the Javascript functions it calls returns all headers except the Set-Cookie header. Thus, my questions are:
Why are the cookies sent back by the API present in the Developer
Tools but do not actually get stored in the browser? (I checked the
browser cookies with an extension and there were none present).
Aren't any cookies sent back by the API to the browser supposed to
be intercepted and stored in the browser's cookie storage? (I also
wonder if this has to do with the run-loop in angular...since my
pages never reload - they are routed using ngRoute with no extra
page loads)
And if the above turns out to be that the Browser will not store
cookies received from a javascript/angular request, how would I
store the cookies? I've seen use of $cookies.mySession =
"cookieContentHere"; but how am I to make use of this if I can't
access the Set-Cookie header?
Thanks for all answers in advance!

Related

Not able to retrieve JSESSIONID cookie with AXIOS

I am trying to call API to authenticate user. getting 200 success response but not getting JSESSIONID cookie in response.
axios.defaults.withCredentials = 'true';
axios.defaults.crossDomain = 'true';
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.headers.post['withCredentials'] = 'true';
const data = {
username: this.state.user,
credential: this.state.pass
}
axios.post('http://3.122.7.162:5000/v60/admin/session', data)
.then(response => {
console.log("response");
console.log(response);
})
.catch(error => {
console.log("error");
console.log(error);
});
Thanks
XMLHttpRequest and fetch (the built-in HTTP request libraries in browsers) do not expose information about cookies in their response object.
It isn't even available through directly reading the Set-Cookie header because it is a forbidden response header.
The only way to read cookie data is through document.cookie, but that only provides information about same origin cookies.
There is no direct way to get the data from a cross-origin cookie using Ajax methods. The only way to do it would be to change the server side code so it returned a copy of the cookie data through another path that the JavaScript could read (e.g. in the response body).
This doesn't stop you using the cookies. Unless third-party cookies are disabled, they will still be set in the browser's cookie jar and automatically sent with future requests to the domain they belong to.

How to set cookies on a response in a ServiceWorker

In a fetch handler triggered by a page navigation, I tried to do this:
return event.respondWith(new Response('Hello!', {
headers: {
"Set-Cookie": "TestCookie=foo; path=/; Max-Age=60;"
"TestHeader": "foo"
}
}));
Then I loaded any URL in the browser, and got the "Hello!" body. In Chrome devtools, I see the TestHeader set in the network panel. But the cookie is not showing up in the network panel, nor in the Application > Cookies viewer. document.cookie also fails to produce it.
The request is initiated by a page navigation, so there's no opportunity to set credentials: "include" on the fetch from the browser tab.
Is it possible to add a cookie to a response in the ServiceWorker? If not, is it possible to write cookies in any other way?
There's some relevant information in the Fetch specification.
As per https://fetch.spec.whatwg.org/#forbidden-response-header-name:
A forbidden response-header name is a header name that is a
byte-case-insensitive match for one of:
Set-Cookie
Set-Cookie2
And then as per item 6 in https://fetch.spec.whatwg.org/#concept-headers-append:
Otherwise, if guard is "response" and name is a forbidden response-header name, return.
This restriction on adding in the Set-Cookie header applies to either constructing new Response objects with an initial set of headers, or adding in headers after the fact to an existing Response object.
There is a plan to add in support for reading and writing cookies inside of a service worker, but that will use a mechanism other than the Set-Cookie header in a Response object. There's more information about the plans in this GitHub issue.
You may try following:
async function handleRequest(request) {
let response = await fetch(request.url, request);
// Copy the response so that we can modify headers.
response = new Response(response.body, response)
response.headers.set("Set-Cookie", "test=1234");
return response;
}

Accessing custom http response headers in angularjs

I am trying to access the header 'error-detail' as you can see in the browser network inspector (link above), the header gets returned. Server-wise I have also added the custom header to the 'Access-Control-Expose-Headers' to allow cross-domain requests as this was suggested to be the fix on other questions.
Below is the request to the server along with the success/error callbacks.
this.signon = function (request, onComplete, onError) {
console.log("Calling server with 'login' request...");
return $http.post("http://localhost:8080/markit-war/services/rest/UserService/login/", request)
.then(onComplete, onError);
};
var onLookupComplete = function(response) {
if (response.data.username)
{
//If user is returned, redirect to the dashboard.
$location.path('/dashboard');
}
$scope.username = response.data.username;
};
var onError = function(response) {
$scope.error = "Ooops, something went wrong..";
console.log('error-detail: ' + response.headers('error-detail'));
};
When I try access the response header as seen below:
console.log(response.headers());
console.log('error-detail: ' + response.headers('error-detail'));
This only outputs:
content-type: "application/json"
error-detail: null
Is there a reason why the error-detail header is not being mapped over to the response object?
I think you are on the right track. To have access to custom headers, your server needs to set this special Access-Control-Expose-Headers header, otherwise your browser will only allow access to 6 predefined header values as listed in the Mozilla docs.
In your screenshot such a header is not present in the response. You should have a look at the backend for this cors header to also be present in the response.
This is a CORS Issue. Because this is a cross-origin request, the browser is hiding most ot the headers. The server needs to include a Access-Control-Expose-Headers header in its response.
The Access-Control-Expose-Headers1 response header indicates which headers can be exposed as part of the response by listing their names.
By default, only the 6 simple response headers are exposed:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
If you want clients to be able to access other headers, you have to list them using the Access-Control-Expose-Headers header.
For more information, see MDN HTTP Header -- Access-Control-Expose-Headers

Read cookies sent by server when using POST request for login

I am doing a POST request for login,when logged in the server send a header "Set-Cookie"
wich I have to get it and put it in the browser.I tryed all those methods none have worked
$.ajax(settings).done(function (data, status, headers, config) {
console.log(data);
//$cookies['Set-Cookie']=response.headers('Set-Cookie');
//console.log(headers);
//console.log(headears()['Set-Cookie']);
//console.log(headears(['Set-Cookie']));
console.log(headers.getResponseHeaders()['Set-Cookie']);
});
The console.log(headers); print "succes" on the console and for the others I get "undefined" or "header is not a function".Can someone please help me.I tryed all the methods I saw in forums none have worked.Thank you.
I lately tryed using this console.log( $cookies.get('xxx')); but the problem is that $cookies.get() works only when the cookies have already been stored in the browser.And I want to get them from the header in the printscreent and add them manually using $cookies.put('myfav','oo'); Thank you.Response Headers
You need to read the actual cookie that Set-Cookie creates.
Try
console.log( $cookies.get('CookieName'));
Also note that if it is an httpOnly cookie you won't have access to it. The same will be true for cross domain requests

how to change the headers for angularjs $http.jsonp

I read the document.
but I think I must have misunderstood it.
$http.defaults.headers.jsonp = { 'Accept' : 'application/json'};
$http.jsonp(url).success(function(data, status, headers, config) {
I also have tried
$httpProvider.defaults.headers.jsonp = { 'Accept' : 'application/json'};
$http.jsonp(url).success(function(data, status, headers, config) {
I wanted to change the Accept to application/json
Neither work.
There is no way to control headers sent by a browser while using JSONP. JSONP is a smart trick (or a hack, depending on how you see it...) that consist of inserting a <script> tag pointing to a server endpoint. Ultimately it is a browser who will decide which headers to sent while requesting scripts via <script> tag and you can't influence it.
More info here: Modify HTTP Headers for a JSONP request

Categories