Thursday, June 8, 2017

Angular2 setting headers in all REST API request | Setting multiple headers in request using Angular service

Angular2 setting headers in all REST API request | Setting multiple headers in request| Headers setting in request with Angular service ... thumbnail 1 summary

Angular2 setting headers in all REST API request | Setting multiple headers in request| Headers setting in request with Angular service


We may need to set custom headers in our all API requests for various purposes.


Ex : adding custom auth header to all requests referred to REST API.

There are many ways you can add your custom headers in the request.

Option 1.Write a service that wraps the original Http object

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

@Injectable()
export class MyHttpClient {

  constructor(private http: Http) {}

  createAuthorizationHeader(headers: Headers) {
    headers.append('auth-custom-hdrs', 'GDFDSFDFSDSD3DFDFDFD'); 
  }

  get(url) {
    let headers = new Headers();
    this.createAuthorizationHeader(headers);
    return this.http.get(url, {
      headers: headers
    });
  }

  post(url, data) {
    let headers = new Headers();
    this.createAuthorizationHeader(headers);
    return this.http.post(url, data, {
      headers: headers
    });
  }
}

And instead of injecting the Http object you could inject this one (MyHttpClient).

import { MyHttpClient } from './http-client';

export class AppComponent {
  // Injected "our" MyHttpClient 
  constructor(http: MyHttpClient) {
    this.http = httpClient;
  }

  handleSomething() {
    this.http.post(url, data).subscribe(result => {
        // console.log( result );
    });
  }
}


Option 2 : Extending BaseRequestOptions which is from from 'angular2/http'.

import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS, Headers, Http, BaseRequestOptions} from 'angular2/http';

import {AppComponent} from './components/index';


class MyRequestOptions extends BaseRequestOptions {
  constructor () {
    super();
    this.headers.append('auth-custom-hdrs','MyCustomHeaderValue');
  }


bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(RequestOptions, { useClass: MyRequestOptions })
]);

This should include 'auth-custom-hdrs' in every service call.

Option 3 : Create a Service and the method in the service will returns all the headers added. Then call this service method and set it into the API request as like below,

Service

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

@Injectable()
export class SessionService {
  constructor () {
    console.log("New SessionService");
  }



public jsonHeaders(): Headers {
        let headers: Headers = new Headers();
        headers.append('Content-Type', 'application/json; charset=utf-8');
        headers.append("Cache-Control", "no-cache");
        headers.append("Cache-Control", "no-store");
        headers.append("If-Modified-Since", "Mon, 26 Jul 1997 05:00:00 GMT");
        headers.append( 'Authorization', this._apptoken);

        return headers;
}
}


and in Your component,

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, URLSearchParams , Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { SessionService } from '../../../_services/session.service';
......

@Injectable()
export class LoginService {
    constructor(private http: Http , private sessionService:SessionService) { }

.
.
.
login(email:string, password:string) {
   
    let params: URLSearchParams = new URLSearchParams();
    params.set('login', email);
    params.set('password', password);
    let requestOptions = new RequestOptions({
                        headers: this.sessionService.jsonHeaders(),
                        method: 'POST'
                    });
    requestOptions.search = params;
    return this.http.get('/login', requestOptions)
            .map((response: Response) => {
                console.log('response ::' + response);
                .
                .
                .
            });
}
}

Sample output :

Host: localhost:8080 Connection: keep-alive Content-Length: 0 Pragma: no-cache Cache-Control: no-cache,no-store Authorization:SDFSDF34DFGDF Origin: http://localhost:8000 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.98.9.3029.110 Safari/537.36 Content-Type: application/json; charset=utf-8 Accept: */* Referer: http://indit-l-141:8000/ Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.8

Hope this helps.

Angular2 session management local storage | Create local session storage | Using localstorage | Angular Session handling with SpringBoot REST API

Angular2 JS session management | Create local session storage | Using localstorage | Angular Session handling with SpringBoot REST API ... thumbnail 1 summary

Angular2 JS session management | Create local session storage | Using localstorage | Angular Session handling with SpringBoot REST API


Through Angular2 login page , REST API returns the unique token if the credentials are validated. We can send this token to all REST API call. We need to store this token in database with encrypted format.
From now on, your AngularJS app will use this token to authenticate to all REST Api exposed.
Temporarily store the token in localStorage ; basically, when the server verifies the credentials, it sends back a new auth-token Ex. </>
app-token : FERTHDFG54GDGDG7KTYRTYRTYRTY
Successive requests will presents the custom header with this value, without the need to manage it and store it with javascript; at every request, server invalidates the token and generates a new one and sends it back to the client --> prevent replay-attacks with a single token.

When the client receives an HTTP status 401 unauthorized response from any REST Api, the angular controller clean all localStorage and redirect the user to the login page.

The server may send HTTP status 401 unauthorized response when the server has not received the app-token for some time (ex 30 minutes). Lets create few sample codes,

1.Creating session.update.service.ts

This will contains methods to set the auth-token.


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

@Injectable()
export class SessionUpdateService {
    setSessionUser(data) {
        localStorage.setItem('user',data.user);
    }
    updateAppTocken(header:Headers) {
        localStorage.setItem('app-awt-token', header.get('app-awt-token'));
    }
}

2.Creating session.service.ts

This will contains methods to get the auth-token, authorized user details. We need to inject this component as globally in our case it will be in AppComponent.

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

@Injectable()
export class SessionService {
  private _status:boolean;
  private _sessionUser:any;
  private _sessionId:string;
  private _apptoken:string;

  constructor () {
    console.log("New Session Service");
  }

getSessionUser() {
         //ToDo :: call REST service to get user
        return this._sessionUser;
}
getCurrentSessionId() {
     //ToDo actual logic
    return this._sessionId;
}
  isLoggedIn() {
      let currentUser = localStorage.getItem('authUser');
      let user = JSON.parse(currentUser);
      let authLogin = localStorage.setItem('authLogin', user.login);
      if (authLogin !== null ) {
        this._status = true;
    }
    return this._status;
  }

  logOut() {
    //ToDo :: call REST service
    this._status = !this._status;
  }
  getAppTocken() {
        this._apptoken = localStorage.getItem('app-awt-token');
        return this._apptoken;
    }


}


3.Creating login.service.ts

This will call our actual REST API to get the auth-token.

import { SessionUpdateService } from '../../../_services/session.update.service';
import { SessionService } from '../../../_services/session.service';
....
....
@Injectable()
export class LoginService {
    constructor(private http: Http , private sessionService:SessionService,  private sessionUpdateService:SessionUpdateService ) { }
token:string;
login(email:string, password:string) {
    let params: URLSearchParams = new URLSearchParams();
    params.set('login', email); 
    params.set('password', password);
    let requestOptions = new RequestOptions({
                        headers: this.sessionService.jsonHeaders(),
                        method: 'POST'
                    });
    this.token = this.sessionService.getAppTocken();
    requestOptions.search = params;
    return this.http.get('store/login', requestOptions)
            .map((response: Response) => {
                console.log('response ::' + response);
                this.sessionUpdateService.updateAppTocken(response.headers);
                // login successful if there's a jwt token in the respons
            });
    // return true;
}
}



4.Creating AppComponent.ts

Add these services to main app component.

import {Component, OnInit} from "@angular/core";
import {SessionService} from './_services/session.service';

@Component({
    selector: "app",
    templateUrl: "./app/app.html",
    providers:[ SessionService ]
})
export class AppComponent implements OnInit {
    ngOnInit() {
        console.log("Application component initialized ...");
    }
    constructor( sessionService: SessionService) {}
}

Services will look this.

@RequestMapping("/estore/login")
 @ResponseBody
 public User login(String login,String password,HttpServletResponse response) {
 
 
 response.addHeader("app-awt-token", RequestContextHolder.currentRequestAttributes().getSessionId()+ "-" +EStoreUtils.genRandomToken());
 
 User user = null;
 try {
  System.out.println("login" + login);
 
  user = userDao.findByEmail(login);
  }
   return user;
 } catch (Exception ex) {
  ex.printStackTrace();
 }
 return null;

}

Hope this helps