2

I'm using angular to POST to an authentication endpoint; on the server side, I can see the request succeed, and proper CORS headers are set. Angular's origin is http://localhost:9000

On the server side, preflight OPTIONS requests always get a 200 back, so that seems OK.

On the client side, the $http.post always fails with an error code of 0, which from other research suggests something is still wrong with CORS. I've read the spec and tried a number of other answers, yet something is still missing.

Angular POSTs like this:

    $http({
        method: 'POST',
        url: 'http://localhost:3000/auth/login',
        data: {
            username: $scope.username,
            password: $scope.password
        }
    })
    .then(function (response) {
         /* etc. etc. */
    }, function (response) {
        /* This always triggers, with response.status = 0 */
        console.log("ERROR: " + response.data);
        console.log("Status: " + response.status);
        console.log("Status text: " + response.statusText);
        console.log("Headers: " + response.headers);

        $scope.error = 'Something went wrong...';
    });

Using curl to debug what the server is sending back, this is it:

< HTTP/1.1 302 Found
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
< Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, Content-Length, X-Requested-With
< Access-Control-Allow-Credentials: true
< Set-Cookie: ua_session_token=(blahblah); Path=/
< Location: /
< Vary: Accept
< Content-Type: text/plain; charset=utf-8
< Content-Length: 23
< Date: Mon, 28 Dec 2015 15:08:17 GMT
< Connection: keep-alive

This is why I'm at a loss, as per the specification, the server seems to be doing the right thing?

Here's what the server gets from the client in terms of request headers:

HEADER host localhost:3000
HEADER content-type application/json;charset=UTF-8
HEADER origin http://localhost:9000
HEADER content-length 38
HEADER connection keep-alive
HEADER accept application/json, text/plain, */*
HEADER user-agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9
HEADER referer http://localhost:9000/
HEADER accept-language en-us
HEADER accept-encoding gzip, deflate

UPDATE tried something else with no luck, based on this post. It would seem Access-Control-Allow-Headers is case-sensitive, and angular is sending on the request accept, origin, content-type. I tweaked the server to parrot back the same, with no luck.

Community
  • 1
  • 1
FrobberOfBits
  • 17,634
  • 4
  • 52
  • 86
  • Have you tried [this](https://github.com/angular/angular.js/issues/3336)? – Yuri Dec 28 '15 at 15:27
  • I did come across that in background research. When you do `OPTIONS` pre-flight to the server, in my case you get a 200 (not a 500 as in that post) and the `Access-Control-Allow-Origin: *` is on that `OPTIONS` preflight request. So I read that whole thread, but it doesn't seem applicable. – FrobberOfBits Dec 28 '15 at 16:50
  • That thread does mention a JSON payload from the server. In my case, there is **no json payload**; when auth succeeds the client gets an auth token and a redirect to a protected resource. Is the lack of a response body (just redirect) a possible cause here? It seems it still wouldn't explain the status being 0, since from the server it's clearly 200. – FrobberOfBits Dec 28 '15 at 16:51

1 Answers1

1

Alright, after applying my head to my keyboard for several hours, I've fixed it.

The answer seems to be that angular really doesn't like getting redirects in response to POST. When I changed the server endpoint to return just a plain auth token as text (the same token it was setting as a cookie anyway) rather than returning a redirect, the angular POST started working like a charm and falling through to the success handler.

Not sure I got deep enough into this to know why angular was behaving in that way; by playing around with it I found that if the redirect the server sent was to a nonexistent (404) URL that this could be replicated, EVEN IF the original POST returned that valid redirect.

FrobberOfBits
  • 17,634
  • 4
  • 52
  • 86