Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS CORS request custom header

I'm having trouble getting CORS enabled on my server in combination with AngularJS. I'm using Angular 1.2.16 and this is my server config:

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name, Authorization"
Header set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Credentials "true"

I can use the following request:

$http.post(configuration.authUrl, {username: 'username', password: 'password'})
    .success(function (data) {
         $cookieStore.put(configuration.sessionName, {
             token: data.authenticationToken,
              user: data.user
         });
    })
    .error(function () {}));

since this request doesn't use a custom header.

When I afterwards try to request the following: Balance.get() with Balance being:

angular.module('portalApp')
    .factory('Balance', ['$resource', 'Auth', 'configuration', function ($resource, Auth, configuration) {
        return $resource(configuration.balanceUrl, {}, {
            get: {
                method: 'GET',
                isArray: false,
                headers: {
                    Authorization: Auth.getAuthToken()
                }
            }
        });
    }]);

I get a 401 Unauthorized on the balanceUrl.

In the config I have put:

$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

I even tried putting $http.defaults.headers.common.Authorization = Auth.getAuthToken(); before the $resource in the Balance resource factory but that didn't help.

The headers being sent to the preflight OPTIONS request don't have the Authorization header, no matter what method I use. These are the request headers of the preflight OPTIONS request.

OPTIONS /api/v1.0/user/orders HTTP/1.1
Host: host
Connection: keep-alive
Cache-Control: no-cache
Access-Control-Request-Method: GET
Pragma: no-cache
Origin: origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: referer
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

Any suggestions?

like image 959
mmjmanders Avatar asked Jun 23 '14 10:06

mmjmanders


2 Answers

As I know you can't use Access-Control-Allow-Origin "*" with Access-Control-Allow-Credentials "true".

like image 84
Miraage Avatar answered Sep 20 '22 00:09

Miraage


After much research I found out the problem wasn't occurring because of the AngularJS or Apache configuration. It was a problem in the backend server app (Java). The urls were restricted for all HTTP methods, so when AngularJS wants to execute the preflight OPTIONS request, the access was denied and a 401 was returned.

This was fixed by doing:

if(!authenticationService.isTokenValid(glueToken) && !((HttpServletRequest)servletRequest).getMethod().equals(HttpMethod.OPTIONS.toString()) ){
  response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
  filterChain.doFilter(servletRequest, servletResponse);
}

In stead of:

if(!authenticationService.isTokenValid(glueToken)){
  response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
  filterChain.doFilter(servletRequest, servletResponse);
}
like image 37
mmjmanders Avatar answered Sep 21 '22 00:09

mmjmanders