8

For some reason, the internet is devoid of examples on how to do this in Angular 4 (which uses TypeScript, which doesn't let you skip including option properties like the JavaScript it transpiles into does).

I'm trying to hit my team's RESTful API, which requires an authentication token, with GET request, like, for example :

return this.http.get(this.BASE_URL + '/api/posts/unseen/all', {
            headers : {
                "Authorization": 'Token token="' + TokenService.getToken() + '"'
            }   
        })

where TokenService is business service class I wrote to return token for use in the app. Upon typing it up, I get greeted with this error instead:

enter image description here

My dependencies in the service file this appears in are:

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';

import { Post } from '../models/post'; // business class 
import 'rxjs/';
import { User } from '../models/user'; // business class
import { HttpService } from './http.service'; // service for connecting us to the base location of the endpoints. provides BASE_URL to any service that extends it
import { TokenService } from './token.service'; // token provider

NOTE: I tried copying and pasting that error, but Visual Studio Code would not cooperate with me doing that.

3
  • 1
    Are there any reason you are not using the new angular httpClient ? Commented Dec 29, 2017 at 5:14
  • My team didn't know of it at the time and already wrote our services for registration,login using http. What is the learning curve on that new API? (Like, how much would I have to change to use it?) Commented Dec 29, 2017 at 5:16
  • 1
    You don't have to change too much things. You only have to define an interceptor of your request. Consider my answer to the question Commented Dec 29, 2017 at 5:27

1 Answer 1

16

Using the new httpClient makes it easier to send token. First you will have to define an interceptor

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  constructor(public auth: AuthService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    request = request.clone({
      setHeaders: {
        Authorization: `Bearer ${this.auth.getToken()}`
      }
    });

    return next.handle(request);
  }
}

You have to add the interceptor to your provider:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from 'token.interceptor';

@NgModule({
  bootstrap: [AppComponent],
  imports: [...],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true
    }
  ]
})
export class AppModule {}

Now when you make any request, the token will be present automatically in the headers.

import { HttpClient } from '@angular/common/http';
// ...
export class AppComponent {

  constructor(public http: HttpClient) {}

  public connectServer() {
    this.http.get('url')
      .subscribe(
        data => console.log(data),
        err => console.log(err)
      );
  }

}

In the interceptor I use a service to check if the token is valid. It is not compulsory as you can define your own authenticationService. But here is one you can use:

import { Injectable } from '@angular/core';
import decode from 'jwt-decode';

@Injectable()
export class AuthService {

  public getToken(): string {
    return localStorage.getItem('token');
  }

  public isAuthenticated(): boolean {
    // get the token
    const token = this.getToken();
    // return a boolean indicating whether or not the token is expired
    return tokenNotExpired(token);
  }

}
Sign up to request clarification or add additional context in comments.

3 Comments

I'm about to try this
Is it possible to only send token in only certain request?
@JonathanLightbringer. You might have received an answer for this but I was trying it by intercepting the URL from request parameter which helps in differentiating the requests and it worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.