161

I have one particular request in my app that requires Basic authentication, so I need to set the Authorization header for that request. I read about setting HTTP request headers, but from what I can tell, it will set that header for all requests of that method. I have something like this in my code:

$http.defaults.headers.post.Authorization = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==";

But I don't want every one of my post requests sending this header. Is there any way to send the header just for the one request I want? Or do I have to remove it after my request?

Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
dnc253
  • 39,967
  • 41
  • 141
  • 157

2 Answers2

324

There's a headers parameter in the config object you pass to $http for per-call headers:

$http({method: 'GET', url: 'www.google.com/someapi', headers: {
    'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
});

Or with the shortcut method:

$http.get('www.google.com/someapi', {
    headers: {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
});

The list of the valid parameters is available in the $http service documentation.

walen
  • 7,103
  • 2
  • 37
  • 58
Yunchi
  • 5,529
  • 2
  • 17
  • 18
  • 1
    I guess I should have looked at the doc a little closer... I was just trying to use the shortcut methods. This works great. Thanks. – dnc253 Aug 09 '12 at 04:56
  • 17
    @dnc253 This works with shortcut methods too. The code would be `$http.get('www.google.com/someapi', {headers: {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}});` – Yunchi Aug 09 '12 at 04:59
  • 1
    Is there a way to extend $http (while maintaining "injectability" and not having to apply it to the default header collection) to automatically add this header for you? Seems kind of redundant to always have to add the header for every secure call you make. – nokturnal Jul 12 '13 at 20:35
  • 1
    @nokturnal You can create your own service `myHttp` which composes `$http` and adds your headers. Then you can inject `myHttp` where you want. – Yunchi Jul 13 '13 at 22:24
  • @woody, I am a complete newb with angular. I tried to do exactly that (I think) but injection failed. I based my solution on this: https://groups.google.com/forum/m/#!msg/angular/72ukcZYeWGE/Qaspjc0qIcgJ – nokturnal Jul 14 '13 at 02:39
  • @nokturnal Refer to the doucmentation for Angular services. If you need more help, you'll get a much better answer if you post your own question. – Yunchi Jul 14 '13 at 13:57
  • @woody, will do. Like I said I am a newb :) – nokturnal Jul 14 '13 at 14:27
  • 32
    Doesn't work for me. None of the headers I add in this way get added to the actual request. – mcv Nov 29 '13 at 09:33
  • so anybody can answer how to send username and password, and explain what base64 is doing in here, and how angular.js can handle this for me? Thanks! – holms May 15 '14 at 10:24
  • 1
    @holms the username and password are being encoded in base64 before being sent to the server. See: http://en.wikipedia.org/wiki/Basic_access_authentication – whoadave May 20 '14 at 20:26
  • 4
    Whenever I try to set the headers, my request goes out as an `OPTION` Request, consequently my endpoint returns a `404 NOT FOUND` which makes sense: It only knows a `GET /someResource` not `OPTIONS /someResource` – Matheus Felipe Apr 09 '15 at 19:17
  • @MatheusFelipe did you get it to work, I have the same problem my request also goes out with OPTION request – SaintTail Apr 10 '15 at 10:33
  • 1
    @SaintTail I got it to work! Sometimes things are so obvious that get overlooked 1- As I had stated before my server didn't know how to reply a `OPTIONS` request. Now I simply created a route for all URI, such as `OPTIONS /*` will call my `MyController.Cors` method. 2- I needed to set the response header as `Access-Control-Allow-Origin", "*"` -- Note that I placed `"*"` because it's just an experiment, in real world you'd want to really filter by the correct expected origin. 2.1- Since I use `AUTHORIZATION` header on my app I also had to set `"Access-Control-Allow-Headers", "Authorization"` – Matheus Felipe Apr 24 '15 at 00:21
  • This looks like it makes sense, but how can I send a dynamic Authorization code? I need my user to login and then have their credentials stored for every post request. Thanks. – Matt Saunders Aug 03 '15 at 10:03
  • 1
    @MatheusFelipe just to add to what you said about the OPTIONS request, I had to do something similar within my API backend because browsers issue an OPTIONS request without the auth header as a preflight to any cross-origin AJAX request. I had it respond 204 (OK, no content) to any URL in my API directory and my auth script has a conditional that skips basic auth if it's an HTTP OPTIONS request. I had to issue Access-Control-Allow-Headers: Authorization in my OPTIONS response as well. – Sam_Butler Apr 07 '16 at 11:14
20

Try this, perhaps it works ;)

.factory('authInterceptor', function($location, $q, $window) {


return {
    request: function(config) {
      config.headers = config.headers || {};

      config.headers.Authorization = 'xxxx-xxxx';

      return config;
    }
  };
})

.config(function($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
})

And make sure your back end works too, try this. I'm using RESTful CodeIgniter.

class App extends REST_Controller {
    var $authorization = null;

    public function __construct()
    {
        parent::__construct();
        header('Access-Control-Allow-Origin: *');
        header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
        if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
            die();
        }

        if(!$this->input->get_request_header('Authorization')){
            $this->response(null, 400);    
        }

        $this->authorization = $this->input->get_request_header('Authorization');
    }

}
Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
donny
  • 439
  • 5
  • 11