I am having trouble with Restangular 1.4 sending authorization headers to an external web api, which challenges if no such header is provided.
In the following code I try to set the default headers to include basic auth header, but when I look at Fiddler it tells me that no authorization header is present from the start, so the api call is rejected as unauthorized.
Does anyone know if this a bug in Restangular, or whether there is something lacking in the way I have tried to code the auth header?
angular.module('MyAPIService', ['restangular']).factory('MyAPIService', function (Restangular) {
Restangular.setBaseUrl('http://mywebapi/api/');
var encoded = Base64.encode(username + ":" + password);
Restangular.setDefaultHeaders({ Authorization: 'Basic ' + encoded });
return Restangular.one('users', username).get();
Try to set headers in configuration block (not sure about factories). My code looks like this:
angular.module('app', ['restangular'])
.config(['RestangularProvider', function (RestangularProvider) {
// ... some code here
RestangularProvider.setDefaultHeaders({
token: 'some-secret-token'
// other headers
});
// ... some code here
}]);
and works for me.
Turns out that the issue is that the Authorization header is null for all preflight (i.e.) OPTIONS request. (to learn about them, see the section on Preflighted Requests at [https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS). So since I was able to control the API's Basic Auth handling, I made the API not issue a 401 challenge for such preflight requests. The Authorization header was present on non-preflight requests (GET,POST,PUT,DELETE).
Related
I need to know Accept-Language request header value in order to make a translation on a page. I've tried to create an interceptor like
$httpProvider.interceptors.push(requestInterceptor);
, but in the method
request: function (config) {
of my interceptor I don't see Accept-Language header. I see Accept, Cache-Control, If-Modified-Since, Pragma but in the browser I do see Accept-Language.
Not all request headers are available in AngularJS request interceptor's config parameter. other header values are browser settings that are added while constructing the request.
You could use, but i'm not sure it gives you the right language.
var language = window.navigator.userLanguage or
window.navigator.language;
Only the server can see the value of Accept-Language. So i think the best way is to get this value from the server response-body and memorize it in you cookies (name example AcceptLanguageCookie) and after that you can overide the Accept-Language someway like this in your interceptor.
var app = angular.module("app", []);
app.config(["$httpProvider", function($httpProvider) {
// set Accept-Language header on all requests
$httpProvider.defaults.headers.common["Accept-Language"] = $cookies.get("AcceptLanguageCookie");
}]);
I need to emulate some state in my developer utility, and for it I need to pass some special cookie to the http request which made via angular $http module.
Code for making http request looks simple:
if (condition){
var headers = getHeaders();
if (headers !== 'undefined'){
config['headers'] = headers;
}
}
return $http(config);
So looks like I should add some field to the this config. But I can't find any related data about this in $http docs.
I do not want to set cookie 'to the browser' becase I want to pass it only for some several requests performed asynchronously.
Is it real to nmake it with angular.js?
This question already has answers here:
Request header field Access-Control-Allow-Headers is not allowed by itself in preflight response
(27 answers)
Closed 6 years ago.
I'm using MEAN Stack User Registration and Login Example & Tutorial as the base for my app. It adds an auth header to every request in the run function:
$http.defaults.headers.common['Authorization'] = 'Bearer ' + $window.jwtToken;
I want to upload images to Cloudinary but I'm getting this error:
XMLHttpRequest cannot load https://api.cloudinary.com/v1_1/xxxx/upload. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
How can I remove this header specifically for requests to Cloudinary?
You will require an interceptor that checks for the url of the request and clears the header if it matches. alternatively you can use the $http config parameter.
Using the parameter:
$http.post('https://api.cloudinary.com/v1_1/' + someId + '/upload', data, { headers: {} });
Using an interceptor:
.factory('cloudinaryInterceptor', function() {
return {
request: function(config){
var authHeader = config.headers('authorization');
//Check for the host
var regex = /api\.cloudinary\.com/i;
if(regex.test(config.url))
//Detach the header
delete config.headers.authorization;
return config;
}
}
});
Remember to push the interceptor in the config phase
$httpProvider.interceptors.push('cloudinaryInterceptor');
This question has been asked before. The answer can be found here.
When you start playing around with custom request headers you will get a CORS preflight. This is a request that uses the HTTP OPTIONS verb and includes several headers, one of which being Access-Control-Request-Headers listing the headers the client wants to include in the request.
You need to reply to that CORS preflight with the appropriate CORS
headers to make this work. One of which is indeed
Access-Control-Allow-Headers. That header needs to contain the same
values the Access-Control-Request-Headers header contained (or more).
I am developing an application using angularJs, resources and jersey rest api's. And I want to implement xsrf protection in my project. Please suggest a better example. I got one example here, but it uses ColdFusion. http://www.bennadel.com/blog/2568-Preventing-Cross-Site-Request-Forgery-CSRF-XSRF-With-AngularJS-And-ColdFusion.htm
Different from given example, you need to do 2 things:
When the main page gets loaded once the user logs in, you need to set a session cookie with name XSRF-COOKIE. Then AngularJS will do the rest by appending a header to every request as stated in documentation (1)
You need to validate every call to your rest API in back-end (for example with an interceptor) by comparing the token in cookie and the one in header. The logic is described on the page you referenced
(1) To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called XSRF-TOKEN on the first HTTP GET request. CSRF Protection section in Documentation
Incase this is your code in jsp/ html page which sets the header and token:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
You can configure the csrf headers for all ajax requests as flollows:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
angular.module("app", [])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common[header] = token;
}]);
And then your http request code will go as follows:
$http({
url: "loadMyData.htm",
method: "POST",
}).success(function(data)
{
console.log(data);
})
create interceptor with below command.
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const cookie = this.cookieService.get('XSRF-TOKEN');
request = request.clone({
headers: new HttpHeaders({
'XSRF-TOKEN': cookie,
}),
withCredentials: true
});
return next.handle(request);
}
I am using $http to make an api call which is sending some custom header like X-Foo. However I can't yet figure out how to read them. Inside the $http({...}).success(function (data, status, headers, config) {...}) function, headers is a function that should give me a hash of all headers but it only shows the header content-type. Is there a way to get the response headers ?
The custom headers will be visible in same domain. However, for the crossdomain situation, the server has to send Access-Control-Expose-Headers: X-Foo, ... header to make the custom headers visible.
Spring 4.0+ provide #CrossOrigin annotation which has following parameters
origins = list of Comma separated origin.
exposedHeaders = list ofcomma separated count custom parameters.
example
#CrossOrigin(origins = "*", exposedHeaders ="X-Total-Count")