Basic Authentication Angular2 (Not CORS) - javascript

I am currently trying to call a jersey REST API that I have running locally on localhost:8080 through Angular 4 using HttpClient.
My Code:
```
ngOnInit() {
const headers = new HttpHeaders();
headers.append('Authorization', 'Basic ' + btoa('username:password'));
headers.append('Content-Type', 'application/json');
this.http.get('http://localhost:8080/mycall?myparam=myvalue', {headers: headers}).subscribe(data => {
console.log(data);
});
}
```
When I make this call I get a 401 error saying that I am Unauthorized. However, when I run this through postman it goes through just fine. What am I doing wrong here?
NOTE: this is not a CORS issue, I am currently allowing CORS through an extension on firefox

HttpHeaders are immutable, so you need to do something like that
ngOnInit() {
const headers = new HttpHeaders()
.append('Authorization', 'Basic ' + btoa('username:password'))
.append('Content-Type', 'application/json');
this.http.get('http://localhost:8080/mycall?myparam=myvalue', {headers: headers}).subscribe(data => {
console.log(data);
});
}
Actually you should not need the Content-type here for a GET request

I think the issue is that you haven't passed in your custom request headers to HttpClient, which is causing the unauthorised error.
Please try something like this.
const headers = new HttpHeaders();
headers.append('Authorization', 'Basic ' + btoa('username:password'));
headers.append('Content-Type', 'application/json');
const options = new RequestOptions({headers: headers});
this.http.get('http://localhost:8080/mycall?myparam=myvalue', options ).subscribe(data => {
console.log(data);
});
You can simply pass in your RequestOptions to http.get as it does accept headers as an optional parameter. Please check following link for more details on the usage.
https://angular.io/api/common/http/HttpClient#get
Also, remember to import RequestOptions as well.

Related

Headers object for fetchAPI is always empty

I have this request function that is wrappers around the fetch API to issue request to my API. But when my frontend app issues request, the headers object is always empty. What am I doing wrong ?
export function request(method, url, payload) {
const body = JSON.stringify(payload);
const headers = new Headers();
headers.append('Content-Type', 'application/json');
const parameters = {
headers: headers,
method: method,
body: body,
cache: "default"
};
return Observable.create(observer => {
fetch(url, parameters)
.then(response => {
observer.next(response);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
}
Have you checked in the network tab of the DevTools if the headers are really missing?
I have the same trouble than you describe, my Header object seems always empty from the Chrome DevTools, but if try to check a specific header like
let headers = new Headers({'X-whatever-name': 'whatever-value'});
myHeader.has('X-whatever-name'); // returns true
Also if I check the detail of the Request Headers in the DevTools (Networking tab), I can see that my custom headers are sent properly.
So only the JS api (entries, keys, ...) seems to be broken for me, but the request is correctly sent.
Try just making it a simple object:
const headers = {
"Content-Type": "application/json"
};

angular rest api call returns https status code 401 ,authentication required

I am hitting an api for getting userinfo, for that I am passing header authorization with value, but in options method it is firing and giving error that https status code 401, authentication required.
I am trying the same with Chrome browser and Postman client tool then it's giving me desired result. Why only my app is throwing such error? It's supposed to give me result if I am giving authorization header for that.
For instance, code is like:
this.http.get(this.url,{headers:this.headers});
Try setting withCredentials : true .
Here is my Working Code. Hope it helps. Also note Iam using new httpclient of Angular 5.
emailsignin(username: string, password: string) { .
let url = this.backendUrl + "/index";
let params = 'username='+username+'&password='+password;
let httpheaders = new HttpHeaders(
{
'Content-Type': 'application/x-www-form-urlencoded'
});
return this._httpclient.post(url, params, {headers: httpheaders, withCredentials : true});
}
You should define your options as a RequestOptions object:
let options = new RequestOptions({ headers: new Headers({ 'Authorization': 'Basic xxxx' }) });
this.http.get(this.url,options );

Angular web service call not sending headers

I m trying to call a web service from Angular. I m passing the headers as HttpHeaders object, but I do not see that sent when I check the Network console.
This other post Angular HttpClient doesn't send header
seems to have answered it, but I am not able to get that working with the solution that is suggested in it .
My call looks like this.
1
this.http.get(urlString, {headers: new HttpHeaders({'Content-Type': 'application/json',
'header1': 'value1',
'header2': 'value2'
})});
2
let myHeaders = new HttpHeaders();
myHeaders = myHeaders.set( 'Content-Type', 'application/json')
.set( 'header1', 'value1')
.set( 'header2', 'value2')
;
this.http.get(urlString, {headers: myHeaders});
3
const httpOptions = {
headers: new HttpHeaders(
{ 'Content-Type': 'application/json',
'header1': 'value1',
'header2': 'value2'
})
};
this.http.get(urlString, httpOptions);
In all cases, the Network console shows this
Access-Control-Request-Headers:content-type,header1,header2
Is there some mistake which I am making when I declare or set it? Sorry if this question is repetition of others, but the answers were not working in this code. Thank you.
Use Headers instead of HttpHeaders
const headers = new Headers({'Content-Type' : 'application/json','header1':'value1','header2':'value2'})
return this.http.get('url', {headers: headers});

Angular5 Creating custom headers

I have this fragment of code (simplified), I try to send a custom header "foo-custom" using http.post, but the request in the browser is sent as a 200 OPTIONS. What is it due?
Import
import { Http, Headers, Response, RequestOptions } from '#angular/http';
App
const myheaders = new Headers();
myheaders.append('Content-Type', 'application/json');
myheaders.append('foo-custom', 'var');
const options = new RequestOptions({headers: myheaders});
this.http.post(
this._url+'search', {}, options
).subscribe(data => {
console.log("CORRECT!");
console.log(data);
}, error => {
console.log("ERROR!");
console.log(error);
});
What is the correct way to do it?
Thanks
It looks like a preflighted request, can you check this comment
Possible duplicated thread?

Basic authentication (or any authentication) with fetch

Couldn't find any documentation on this, so before I dig deep in code does anyone out there know how to use basic authentication when making a REST request using 'fetch' (https://github.com/github/fetch).
Just tried the following line, but the header was not set in the request:
fetch('http://localhost:8080/timeEntry', {
mode: 'no-cors',
headers: { 'Authorization': 'Basic YW5kcmVhczpzZWxlbndhbGw=' }
})
.then(checkStatus)
.then(parseJSON)
.then(function(activities) {
console.log('request succeeded with JSON response', data);
dispatch(activitiesFetched(activities, null));
}).catch(function(error) {
console.log('request failed', error);
dispatch(activitiesFetched(null, error));
});
The username and password is my own first and last name, using curl it works.
If I put { 'Accept' : 'application/test' } Accept is set, just not Authorization... strange.
Just for me to able to continue I added credentials: 'include' which makes the browser to prompt for username and password which is used for communicationg with the REST backend. Just for testing, will use OAuth further on.
fetch('http://localhost:8080/timeEntry', {
mode: 'no-cors',
credentials: 'include'
})
.then(checkStatus)
.then(parseJSON)
.then(function(activities) {
console.log('request succeeded with JSON response', data);
dispatch(activitiesFetched(activities, null));
}).catch(function(error) {
console.log('request failed', error);
dispatch(activitiesFetched(null, error));
});
no-cors mode prevents the headers from being anything other than simple headers.
"Authorization" header doesn't fit to simple headers. See more here: https://developer.mozilla.org/en-US/docs/Web/API/Request/mode
Note that if you use fetch with Authorization header you will NOT establish a session. You will have to manually add that header for every request. Navigating to secured path would also not be possible.
So to make this work You should pre-authenticate with XMLHttpRequest. You can do this like so:
var authUrl = location.origin + '/secured-path/';
var http = new XMLHttpRequest();
http.open("get", authUrl, false, login, pass);
http.send("");
if (http.status == 200) {
//location.href = authUrl;
} else {
alert("⚠️ Authentication failed.");
}
Note that above is synchronous so you don't need a callback here.
So after doing this you can use fetch without headers e.g. this request should be successful:
fetch(authUrl, {
method: 'get',
}).then(function(response) {
console.log(response);
});
Since it looks like the library you are using is a polyfill for Fetch API, I'm going to work off of the assumption that the syntax should carry through as well.
The samples I found on Mozilla's page indicate that the fetch method signature is fetch('API_ENDPOINT', OBJECT) where object looks like:
myHeaders = new Headers({
"Authorization": "Basic YW5kcmVhczpzZWxlbndhbGw="
});
var obj = {
method: 'GET',
headers: myHeaders
})
So the method becomes:
fetch('http://localhost:8080/timeEntry', obj)
.then(checkStatus)
.then(parseJSON)...
I have not tested this code, but it seems consistent with what I was able to find. Hope this points you in the right direction.

Categories