I'm getting a problem when I try to call my WebApi, I need to send in a request header the authorization credentials, but, I'm not getting it up.
My resquest header need to be like this image of the request header generated by my REST tester
Authorization:Basic dXNlcm5hbWU6cGFzc3dvcmQ=
But, when I try to set it on Angular using this code block
$http.defaults.headers.Authorization = 'Basic ' + credentials;
return $http.post('http://localhost:2703/api/Authenticate');
Or this
return $http.post('http://localhost:2703/api/Authenticate', {
headers: { 'Authorization': 'Basic ' + credentials }
});
My request header became like this one
Access-Control-Request-Headers: accept, authorization
Can someone tell me what am I doing wrong? Any help will be appreciated. :)
You can do something like this:
var header = {headers: {'Authorization': 'Basic ' + credentials}}
$http.post(url, payload, header)
.success(function (data) {
//stuff
}
I couldn't resolve my problem using a cross domain request, so, I've configure my Web Api and Web App in the same domain. Doing this, I can change the headers normally and send a post request as I need.
Related
We are trying to get our Office Excel add-in to contact one of our own Web API services so it can send and receive data from it. For the request to be authorised we must fill out the Authorization header attribute. This is how we are doing the request, which works perfectly well in all of our normal web applications.
this.LoginAuth = function (authString) {
$http.defaults.headers.common.Authorization = 'Basic ' + authString;
return $http({
url: MainFactory.GetWebAPILocation() + '/API/User/AddInLoginAuth',
dataType: 'json',
method: 'POST',
data: {},
headers: {
"Content-Type": "application/json"
}
});
}
However, when the request is made through the add-in the Authorization attribute has been cleared down causing our request to fail. Is this clearing of the attribute being done by Excel? And if so, is there a way in which we can stop it?
Turns out this was a CORS issue in our Web API service.
I am building an Ionic app, and trying to set custom headers for every GET request I do on the app.
This is the CustomHeaderController
angular.module('myHeader',[])
.controller('headerCtrl',['customHeader',function(customHeader){
var config = {headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'text/html;odata=verbose',
"X-Request-from" : "{{vm.data.os}}" }};
$http.get('http://localhost:8100, config); }])
At the moment when I inspect the page, I do not get any custom header, just the default one.
Any clues? Appreciate it! Cheers.
You need to use interceptor in this case with every http request.
Interceptor Details
I am trying to send a request to my backend which uses HTTP Basic auth for authentication.
For testing purposes
username: user
password: password
so the correct header is:
Authorization: Basic dXNlcjpwYXNzd29yZA==
I have tested the request with this header in Chrome Advanced Rest Extension and it works:
I generated the request in Angular2 like this:
public getCurrentCounter() {
console.log("Method getCurrentCounter() in CounterService called");
var request = this.backendURL + "counter";
var header = this.generateHeader(this.username, this.password);
console.log(header);
return this._http.get(request, {
headers: header
})
.map(res => res.json());
}
/**
* Generate HTTP header using HTTP basic Auth
*/
private generateHeader(username, password) {
var base64Creds = btoa(username + ":" + password);
var auth = 'Basic ' + base64Creds;
console.log(auth);
var authHeader = new Headers();
authHeader.append("Authorization", auth);
return authHeader;
}
I logged the generated Header Object and it looks like this:
Still I get this response:
XMLHttpRequest cannot load http://localhost:8080/counter. Response for preflight has invalid HTTP status code 401
Anybody an idea what could be wrong?
The problem is related to CORS which is not enabled on the server side.
Your service must answer an OPTIONS request with headers like these:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: [the same ACCESS-CONTROL-REQUEST-HEADERS from request]
Here is a good doc: http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server
also look at this: Chrome v37/38 CORS failing (again) with 401 for OPTIONS pre-flight requests
for the basic authentication in angularjs 1.x could you please try:
service.SetCredentials = function (username, password) {
var authdata = Base64.encode(username + ':' + password);
$http.defaults.headers.common = {"Access-Control-Request-Headers": "accept, origin, authorization"}; //you probably don't need this line. This lets me connect to my server on a different domain
$http.defaults.headers.common['Authorization'] = 'Basic ' + authdata; // jshint ignore:line
};
for the Angularjs 2.x version please have a look at:
Angular2 - set headers for every request
I found extending the BaseRequestOptions very interesting:
class MyRequestOptions extends BaseRequestOptions {
constructor () {
super();
this.headers.append('Authorization', 'Basic ' + authdata);
}
}
I hope it helps
So turns out the problem was on the backend.
The backend expected the OPTIONS request to be base authenticated as well, but since the OPTIONS request sent from angular2 doesn't have the Authentication Headers, we got an 401 response.
Limiting the request types which are expected to be authenticated on the backend fixed the issue.
Either you forgot to import the Headers class. Either you need to set the withCredentials property to true on the underlying XHR of your request.
To do that, you can do the following. First extend the BrowserXhr:
#Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.withCredentials = true;
return <any>(xhr);
}
}
and override the BrowserXhr provider with the extended class:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
Can you verify but it seems that you getting this error from an OPTIONS request ? and not a GET request.
As the title suggest, I need to pass an authorization token but when I check the network console, I'm getting a 403 because the accept and authorization isn't there. NOTE: I removed my authorization token for this example
$http({
url: 'http://api.stubhub.com/search/catalog/events/v2?title="san"',
dataType: 'json',
method: 'GET',
data: '',
headers: {
"Content-Type": 'application/json',
"Authorization": 'Bearer {token}'
}
}).success(function(response){
$scope.searchResponse = response;
}).error(function(error){
$scope.error = error;
});
This seems like correct syntax? What's wrong here?
EDIT: added the XHR screenshot
EDIT: 2. Here's my network traffic, HAR via paste bin:
http://pastebin.com/fiFngZSy
setting custom headers on XHR requests triggers a preflight request.
I bet you're seeing an OPTIONS request without the Authorization header, and a corresponding response whose Access-Control-Allow-Headers header value is not listing Authorization, or the API doesn't even allow unauthorized OPTIONS requests.
I don't know the stubhub api, but does it return CORS-compliant responses?
I am facing a weird issue. I am running my angularjs app in nodejs server locally which calls a POST API from my app located on Google App Engine. The API is configured with all CORS headers required as follows:
def post(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers.add_header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
self.response.headers.add_header("Access-Control-Allow-Headers", "X-Requested-With, content-type, accept, myapp-domain")
self.response.headers["Content-Type"] = “application/json; charset=utf-8”
GET requests to the API work without issues.
POST requests to the API work but ONLY when I send the post data as a 'string of params' and NOT when post data is sent as an object which is the right way to do. Eventually I need to be able to upload pictures using this API so the first solution below might not work for me. Please help!
METHOD 1: This works:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = "conversationid=1c34b4f2&userid=67e80bf6&content='Hello champs! - Web App'";
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz",
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
METHOD 2: This fails:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = ({
'conversationid' : '1c34b4f2',
'userid' : '67e80bf6',
'content' : 'Hello champs! - Web App'
});
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz"
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
When I use METHOD 2 it fails with the following error in the console:
XMLHttpRequest cannot load https://myapp-qa.appspot.com/message.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://0.0.0.0:8000' is therefore not allowed access.
Please let me know if you have any solution. Thanks in advance.
The issue is most likely with Angular sending a pre-flight OPTIONS request to check the access headers from the server. I am not sure how OPTIONS requests are handled in your API, but I am betting these headers are not being added. I suggest installing Fiddler to monitor the actual requests to see what is going on with the headers. You may only be adding them to your POST responses.
See this answer for details on why METHOD 1 may work in this scenario, while METHOD 2 does not.
Here are some more details about pre-flight requests.