How do I access response headers using HttpClient in Angular 5? - javascript

I have written an authentication service in Angular 5 which does a POST request to my backend using the HttpClient class. The backend responds by sending a JWT bearer token.
My request looks like this:
return this.http.post('http://127.0.0.1:8080/api/v1/login', {
'username': username,
'password': password
}, {
headers: new HttpHeaders()
.set('Content-Type', 'application/json')
})
.toPromise()
.then(response => {
console.log(response);
return response;
});
}
How do I access the authorization header of the response?
When I write the response to the console, like above, it says 'null'. I know the error is not in the backend because I captured the traffic and the backend is indeed sending the bearer token.
Any help is very much appreciated.

To access the full response (not just the body of the response), you must pass the observe: 'response' parameter option in your http request. Now you can access the headers with res.headers
return this.http.post('http://127.0.0.1:8080/api/v1/login', {
'username': username,
'password': password
}, {
headers: new HttpHeaders()
.set('Content-Type', 'application/json'),
observe: 'response'
})
.map(res => {
let myHeader = res.headers.get('my-header');
});
Docs

Related

Why do I get error code 401 when sending post request

From the following request I get status code 302 redirect. But I want to send cookies I've received from the response with the redirect to the next page. Right now I get status code 401 when sending the request, and I've figured out that it's because I need to send the cookies along with the redirect, but I don't get the cookies until I fetch the url that gives me the redirect. How do I do that?
async function login (url) {
let request = await fetch(url, {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type' : 'application/x-www-form-urlencoded' },
body: 'username=name&password=pass&submit=login',
})
return request
}
In general body data type must match the Content-Type header. so in your case you have to use
body: new URLSearchParams({
'userName': 'name',
'password': 'pass',
'grant_type': 'password'
}),

Node/Express - res.status().send() only sends the status but does not send an object

I am having an issue with a route in my backend where res.status().send() will only send the client the status code, but it will not send the client the object located inside of send().
Here is my code (redacted all code but the problem for brevity):
exports.user_signup = (req, res) => {
const { body } = req;
const { companyName, password, email } = body;
User.find({ email: email }, (err, previousUsers) => {
if (err) {
return res.status(400).send({
message: "There was an issue signing up."
});
} else if (previousUsers.length > 0) {
return res.status(403).send({
message: "Records show this email is linked to another account."
});
}
}
When I make my fetch request from the client, the response only returns the status code from the server, but nowhere in the response is the object in the send() method on the server. Just spitballing, I threw res.status(200).json(object) at it to send the object as json to no avail.
Here is my `fetch request from the client:
fetch("http://localhost:3000/users/accounts/", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
}).then(response => console.log(response));
}
To show what response I am getting, I purposely posted some form data from the client to the route that would throw the 403 error, and this is the response I get in the browser console:
Response {type: "basic", url: "http://localhost:3000/users/accounts/", redirected: false, status: 403, ok: false, …}
So I am able to successfully send the status back from the route to the client, however I can not for the life of me figure out why send() does not send the object along with it.
The body of the response that comes back from fetch() is a ReadableStream. You need to process it to turn it into something usable. Normally you would call response.json() to parse it as a JSON object:
fetch("http://localhost:3000/users/accounts/", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
})
.then(response => response.json())
.then(response => console.log(response));
}

Vue.js Fetch throws 404 and api response

I can't make a POST request in Vue.js. It was giving me CORS issues, but I added
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
to the API and they went away. I can get valid responses from the API using Postman while using the same email and password (Postman ignores CORS).
Here is my Fetch request:
<script>
export default {
data () {
return {}
},
methods : {
login : function () {
console.log('Logging in');
// axios({
// method : 'post',
// url : 'https://www.example.com/login',
// headers : {'content' : 'application/json'},
// data : {
// email : 'emailHere',
// password : 'passwordHere'
// }
// })
// .then(function (response) {
// console.log(response);
// })
// .catch(function (error) {
// console.log(error);
// });
fetch('https://www.example.com/login', {
method: 'POST',
body: JSON.stringify({
email : 'emailHere',
password : 'passwordHere'
})
})
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.error(err))
}
}
}
</script>
https://www.example.com/api/v1/authenticate/login 404 (Not Found)
{status: false, message: "Invalid credentials"}
I tried Axios, and still gives me 404, but not the "Invalid Credentials" response.
In other applications I have used jquerys ajax successfully with the same API, so the API seems to allow javascript requests. But Fetch and Axios don't like it.
I have a Login.vue component that has a button
<a id="login-btn" #click.prevent="login">{{ $t('loginPage.loginButtonText') }}</a>
Any help would be appreciated! Thanks!
You are missing Content-Type header. Try setting headers in your request. Fetch demands that you set headers explicitly since it is a low-level API. Your server may reject as it doesn't recognize appropriate Content-Type. Try this:
fetch('https://www.example.com/login', {
method: 'POST',
// THIS IS IMPORTANT
headers: new Headers({
'Content-Type': 'application/json',
'Accept': 'application/json',
}),
body: JSON.stringify({
email : 'emailHere',
password : 'passwordHere'
})
})
Also, remember two things with fetch:
First getting 404 using fetch doesn't mean that your request has failed. If a server responds 4xx or 5xx error, then fetch is considered successful. Only when a network error occurs, fetch is rejected. So if you get 404, it means the request has reached server but there is a problem with the client side.
Second, try setting mode to cors in you fetch request. Thought the default value of mode is cors.

Spring: request body missing error when sent from client but works with postman?

I have a Spring Rest backend setup as well as a react client. Both are setup on different local ports. I am trying to send a simple request from my React client using a fetch call to my spring rest api.
When sending the POST request using Postman, the API responds as expected.
When sending the request from the React client I receive the following 400 error:
org.springframework.http.converter.HttpMessageNotReadableException:
Required request body is missing: public
org.springframework.http.ResponseEntity<?>
I have done the following:
Disabled CSRF on my spring application.
Set global CORS config to accept all requests.
Ensured on multiple occasions that the request body is correct and identical to that sent via Postman.
Here is my Fetch request from react client:
fetch(API_BASE_URL + '/api/auth/signin', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json;charset=UTF-8',
'Access-Control-Request-Method': 'POST'
}),
body: {
username: this.state.uname,
password: this.state.password,
}
}).then(
function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function (data) {
let json = JSON.parse(data);
let token = json.tokenType + " " + json.accessToken;
localStorage.setItem(ACCESS_TOKEN, token);
alert('successfully saved token:' + token);
});
}
)
.catch(function (err) {
console.log('Fetch Error :-S', err);
});
For those interested:
The data passed in payload was of an incorrect format. While this may not appear logical, creating a variable as so:
let payload = {
username: this.state.username,
password: this.state.password,
};
And passing that as the body to fetch seems to work.
Hopefully this may help others facing the same problem..

Angular 4 JWT token shows "401 unauthorized"

I've seen similar threads to this issue, but I had no luck solving it.
I'm trying to access my .net core controller "GET" using angular post.
getAll() {
return this.http.get('api/Users/GetAll', this.jwt()).map((response: Response) => response.json());
}
I'm getting this error :
401 Unauthorized
jwt code :
private jwt() {
// create authorization header with jwt token
let currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}');
if (currentUser && currentUser.token) {
let headers = new Headers({ 'Content-Type': 'application/json' });
headers.append('Authorization', 'Bearer ' + currentUser.token)
return new RequestOptions({ headers: headers });
}
}
currentUser.token consist a valid token, I can access it via console.log, etc.
What am I doing wrong?

Categories

Resources