2

How can I change the code in order to take the token because it is always null? The console doesn't return any error and in the postman(application) the server side works correctly.

I have this code in the server side:

 router.post('/', async (req, res) => {
  const { error } = validate(req.body); 
  if (error) return res.status(400).send(error.details[0].message); 
  let user = await User.findOne({ username: req.body.username });     
  if (!user) return res.status(400).send('Invalid username or password.');  

  const validPassword = await bcrypt.compare(req.body.password, 
  user.password); //to bcrypt pairnei to req.body.pass kai to kanei encrypt 
  me to hash kai to sygkrinei me to user.password pou brisletai sth bash
  if (!validPassword) return res.status(400).send('Invalid username or password.');

  const token = user.generateAuthToken();
  res.header('X-OBSERVATORY-AUTH', token).header('Access-Control-Expose-Headers', 'X-OBSERVATORY-AUTH').send(_.pick(user, ['_id', 'email', 'username','isAdmin']));
  });
 }

and the code of angular in client side:

login( username: string,  password: string) {
var user: User = {  username: username, password: password };
this.http
  .post<any>("http://localhost:3000/api/auth",user, {observe:'response'})
  .subscribe((res) => {
    const token = res.headers.get('X-OBSERVATORY-AUTH');
    console.log(token);
    this.token = token;
    if (token!==null) {
      this.isAuthenticated = true;
      this.userId = res.body._id;
      this.isAdmin=res.body.isAdmin;
      this.authStatusListener.next(true);
      this.saveAuthData(token, this.userId, this.isAdmin); 
    }
  });
}
Christy Nakou
  • 393
  • 1
  • 2
  • 14

1 Answers1

3

It seems an issue with the HTTP response, not with the Angular.

The backend is not adding the header X-OBSERVATORY-AUTH to the Access-Control-Expose-Headers

The browser won't allow the application to access all http response headers. If you wanna allow some header to be accessible, you must add it to the Access-Control-Expose-Headers.

You can find more information here https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

EDIT: I don't know much about node.js but it seems that the only thing you have to do is:

...
res.header('X-OBSERVATORY-AUTH', token).header('Access-Control-Expose-Headers', 'X-OBSERVATORY-AUTH')
...
Leandro Lima
  • 1,164
  • 6
  • 12
  • 1
    Interesting. I always assumed that if an HTTP response contained some HTTP header ... then Javascript could simply read it. That's apparently NOT the case ... especially with a CORS scenario ... like Angular. Thank you for the info! Here's another useful link: [SO: Why is Access-Control-Expose-Headers needed?](https://stackoverflow.com/questions/25673089/) – paulsm4 Feb 28 '19 at 17:21
  • I add that in my code, but still doesn't work, the console returns null – Christy Nakou Mar 01 '19 at 10:31
  • Are you receiving the Access-Control-Expose-Headers in the response? If that's not the issue, then I don't know what it could be =/ – Leandro Lima Mar 01 '19 at 17:31