Angular sending token with get (and other) requests
Asked Answered
H

1

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.

Humperdinck answered 29/12, 2017 at 4:59 Comment(3)
Are there any reason you are not using the new angular httpClient ?Patriapatriarch
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?)Humperdinck
You don't have to change too much things. You only have to define an interceptor of your request. Consider my answer to the questionPatriapatriarch
P
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);
  }

}
Patriapatriarch answered 29/12, 2017 at 5:26 Comment(3)
I'm about to try thisHumperdinck
Is it possible to only send token in only certain request?Yuki
@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.Zambrano

© 2022 - 2024 — McMap. All rights reserved.