0

I have an ExpressJS API running with ng2 (rc4) on the front end. I am currently reading up on how to protect some endpoints on my API using JWT.

Currently, I can send a login request from the front end, have it picked up, checked and if valid, have a JWT passed back in the response. I am then adding this to local storage.

With each request I then pass the token along in the headers. Should I receive a 403 in the response, I am planning to redirect the user to a login page.

My issue currently is in that when I pass my request to the API, I am getting 403 response.

I have pulled out the code I believe is relevant below :

Express API - auth.js - this is called when a http request is sent to a protected endpoint

    function CheckTokenIsValid(req, res, next) {

    var token = req.body.token || req.query.token || req.headers['x-access-token'];

    if (token) {
        jwt.verify(token, app.get('superSecret'), function(err, decoded) {
            if (err) {
                return res.json({
                    success: false,
                    message: 'Failed to authenticate token.'
                });
            } else {
                req.decoded = decoded;
                next();
            }
        });
    } else {
        return res.status(403).send({
            success: false,
            message: 'No token provided.'
        });
    }
}

ng2 - home.component.ts - onTestGet() is triggered by an ngSubmit on the home

export class HomeComponent {
getData: string;

constructor(private _contentService: ContentService) { }

onTestGet() {
    this._contentService.getContent('http://localhost:8080/api/config', '')
        .subscribe(
        data => this.getData = data.site,
        error => console.log('error'),
        () => console.log(this.getData)
        );
}

}

ng2 - content.service.ts - this is called by onTestGet()

import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Http, URLSearchParams} from '@angular/http';
import {Headers} from '@angular/http';

@Injectable()
export class ContentService {
    constructor(private _http: Http) { }

    getContent(api: string, max: string) {
        return this.makeRequest(api, max);
    }

    private makeRequest(path: string, max: string) {

        let headers = new Headers();
        headers.append('Content-Type', 'application/json');
        let authToken = localStorage.getItem('auth_token');
        headers.append('Authorization', `Bearer ${authToken}`);

        let params = new URLSearchParams();
        params.set('results', max);
        let url = path;
        return this._http.get(url, { headers }).map(res => res.json());
    }
}

I can see from the developer tools, that after logging in a token is correctly stored, a token that if I send via POSTMAN, is accepted and valid.

Contents of local storage after log in

Any suggestions on where I am going wrong would be much appreciated.

EDIT: Ok if I update the following :

headers.append('Authorization', `Bearer ${authToken}`);

so it is now

headers.append('x-access-token', `${authToken}`);

it works, however I am unsure if this is best practice?

Sangwin Gawande
  • 7,658
  • 8
  • 48
  • 66
JL Pikun
  • 15
  • 5

1 Answers1

1

Since you're sending your token in the authorization header you can get it in the backend by replacing:

var token = req.body.token || req.query.token || req.headers['x-access-token'];

by

const authorization = req.headers.authorization;

let token;

if (authorization) {
  token = authorization.split(' ')[1]; // since Bearer in 0 and your token is 1
} else {
  return res.status(404).json({ error: 'No token provided' });
}
Rakhat
  • 4,783
  • 4
  • 40
  • 50
khocef
  • 105
  • 11