Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 8155c3a

Browse files
sam-mccallIgorMinar
authored andcommitted
feat($http): allow overriding the XSRF header and cookie name
Add 'xsrfCookieName' and 'xsrfHeaderName' property to $httpProvider.defaults and http config object, which give the name of the cookie the XSRF token is found in, and the name of the header it is sent in, respectively. This allows interop with servers with built-in XSRF support that use different names. The defaults match the current hard-coded values of 'XSRF-TOKEN' and 'X-XSRF-TOKEN'.
1 parent b001c8e commit 8155c3a

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

src/ng/http.js

+21-7
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,10 @@ function $HttpProvider() {
149149
},
150150
post: {'Content-Type': 'application/json;charset=utf-8'},
151151
put: {'Content-Type': 'application/json;charset=utf-8'}
152-
}
152+
},
153+
154+
xsrfCookieName: 'XSRF-TOKEN',
155+
xsrfHeaderName: 'X-XSRF-TOKEN'
153156
};
154157

155158
var providerResponseInterceptors = this.responseInterceptors = [];
@@ -383,9 +386,10 @@ function $HttpProvider() {
383386
* {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
384387
* an unauthorized site can gain your user's private data. Angular provides following mechanism
385388
* to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
386-
* called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
387-
* runs on your domain could read the cookie, your server can be assured that the XHR came from
388-
* JavaScript running on your domain. The header will not be set for cross-domain requests.
389+
* (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
390+
* JavaScript that runs on your domain could read the cookie, your server can be assured that
391+
* the XHR came from JavaScript running on your domain. The header will not be set for
392+
* cross-domain requests.
389393
*
390394
* To take advantage of this, your server needs to set a token in a JavaScript readable session
391395
* cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
@@ -395,6 +399,9 @@ function $HttpProvider() {
395399
* up its own tokens). We recommend that the token is a digest of your site's authentication
396400
* cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
397401
*
402+
* The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
403+
* properties of either $httpProvider.defaults, or the per-request config object.
404+
*
398405
*
399406
* @param {object} config Object describing the request to be made and how it should be
400407
* processed. The object has following properties:
@@ -405,6 +412,8 @@ function $HttpProvider() {
405412
* `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
406413
* - **data** – `{string|Object}` – Data to be sent as the request message data.
407414
* - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
415+
* - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
416+
* - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
408417
* - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
409418
* transform function or an array of such functions. The transform function takes the http
410419
* request body and headers and returns its transformed (typically serialized) version.
@@ -513,12 +522,17 @@ function $HttpProvider() {
513522
function $http(config) {
514523
config.method = uppercase(config.method);
515524

525+
var xsrfHeader = {},
526+
xsrfCookieName = config.xsrfCookieName || defaults.xsrfCookieName,
527+
xsrfHeaderName = config.xsrfHeaderName || defaults.xsrfHeaderName,
528+
xsrfToken = isSameDomain(config.url, $browser.url()) ?
529+
$browser.cookies()[xsrfCookieName] : undefined;
530+
xsrfHeader[xsrfHeaderName] = xsrfToken;
531+
516532
var reqTransformFn = config.transformRequest || defaults.transformRequest,
517533
respTransformFn = config.transformResponse || defaults.transformResponse,
518534
defHeaders = defaults.headers,
519-
xsrfToken = isSameDomain(config.url, $browser.url()) ?
520-
$browser.cookies()['XSRF-TOKEN'] : undefined,
521-
reqHeaders = extend({'X-XSRF-TOKEN': xsrfToken},
535+
reqHeaders = extend(xsrfHeader,
522536
defHeaders.common, defHeaders[lowercase(config.method)], config.headers),
523537
reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn),
524538
promise;

test/ng/httpSpec.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -453,22 +453,27 @@ describe('$http', function() {
453453

454454

455455
it('should set the XSRF cookie into a XSRF header', inject(function($browser) {
456-
function checkXSRF(secret) {
456+
function checkXSRF(secret, header) {
457457
return function(headers) {
458-
return headers['X-XSRF-TOKEN'] == secret;
458+
return headers[header || 'X-XSRF-TOKEN'] == secret;
459459
};
460460
}
461461

462462
$browser.cookies('XSRF-TOKEN', 'secret');
463+
$browser.cookies('aCookie', 'secret2');
463464
$httpBackend.expect('GET', '/url', undefined, checkXSRF('secret')).respond('');
464465
$httpBackend.expect('POST', '/url', undefined, checkXSRF('secret')).respond('');
465466
$httpBackend.expect('PUT', '/url', undefined, checkXSRF('secret')).respond('');
466467
$httpBackend.expect('DELETE', '/url', undefined, checkXSRF('secret')).respond('');
468+
$httpBackend.expect('GET', '/url', undefined, checkXSRF('secret', 'aHeader')).respond('');
469+
$httpBackend.expect('GET', '/url', undefined, checkXSRF('secret2')).respond('');
467470

468471
$http({url: '/url', method: 'GET'});
469472
$http({url: '/url', method: 'POST', headers: {'S-ome': 'Header'}});
470473
$http({url: '/url', method: 'PUT', headers: {'Another': 'Header'}});
471474
$http({url: '/url', method: 'DELETE', headers: {}});
475+
$http({url: '/url', method: 'GET', xsrfHeaderName: 'aHeader'})
476+
$http({url: '/url', method: 'GET', xsrfCookieName: 'aCookie'})
472477

473478
$httpBackend.flush();
474479
}));

0 commit comments

Comments
 (0)