Created
November 14, 2016 14:39
-
-
Save leon/e35630ac6a111a4e1b2c9edebee1de16 to your computer and use it in GitHub Desktop.
secure-http angular2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { isString } from 'lodash'; | |
import { | |
Http, | |
ConnectionBackend, | |
Headers, | |
Request, | |
RequestOptions, | |
RequestOptionsArgs, | |
Response, | |
RequestMethod, | |
} from '@angular/http'; | |
import { Observable } from 'rxjs/Observable'; | |
import { ErrorObservable } from 'rxjs/observable/ErrorObservable'; | |
import { SecurityService } from './security.service'; | |
import { CookieService } from '../cookie'; | |
/** | |
* Custom Http client that handles conversions to json, adds CSRF token, and jwt token and redirects to signin if token is missing | |
*/ | |
export class SecureHttp extends Http { | |
constructor( | |
backend: ConnectionBackend, | |
defaultOptions: RequestOptions, | |
private securityService: SecurityService, | |
private cookieService: CookieService | |
) { | |
super(backend, defaultOptions); | |
} | |
request(url: string | Request, options?: RequestOptionsArgs): Observable<any> { | |
if (typeof url === 'string') { | |
return this.get(url, options); // Recursion: transform url from String to Request | |
} | |
return this.sendRequest(url, options); | |
} | |
get(url: string, options?: RequestOptionsArgs): Observable<any> { | |
return this.sendRequest({ method: RequestMethod.Get, url: url, body: '' }, options); | |
} | |
post(url: string, body: string, options?: RequestOptionsArgs): Observable<any> { | |
return this.sendRequest({ method: RequestMethod.Post, url: url, body: body }, options); | |
} | |
put(url: string, body: string, options?: RequestOptionsArgs): Observable<any> { | |
return this.sendRequest({ method: RequestMethod.Put, url: url, body: body }, options); | |
} | |
delete(url: string, options?: RequestOptionsArgs): Observable<any> { | |
return this.sendRequest({ method: RequestMethod.Delete, url: url, body: '' }, options); | |
} | |
patch(url: string, body: string, options?: RequestOptionsArgs): Observable<any> { | |
return this.sendRequest({ method: RequestMethod.Patch, url: url, body: body }, options); | |
} | |
head(url: string, options?: RequestOptionsArgs): Observable<any> { | |
return this.sendRequest({ method: RequestMethod.Head, url: url, body: '' }, options); | |
} | |
private sendRequest(requestOptionsArgs: RequestOptionsArgs, options?: RequestOptionsArgs): Observable<any> { | |
let requestOptions = new RequestOptions(requestOptionsArgs); | |
// Convert body to stringified json if it's not a string already | |
if (!isString(requestOptions.body)) { | |
requestOptions.body = JSON.stringify(requestOptions.body); | |
} | |
// Get xsrf token from spring security cookie | |
const csrfToken: string = this.cookieService.get('XSRF-TOKEN'); | |
let baseOptions: RequestOptions = new RequestOptions({ | |
headers: new Headers({ | |
'Content-Type': 'application/json', | |
'X-Requested-With': 'XMLHttpRequest', | |
'X-XSRF-TOKEN': csrfToken | |
}) | |
}); | |
return this.securityService.accessToken$.mergeMap(token => { | |
// If there is a token we add it to the baseOptions | |
if (token) { | |
baseOptions.headers.set('Authorization', 'Bearer ' + token); | |
} | |
// We create a request from the passed in method, url, body and merge our base options in there | |
let request = new Request(baseOptions.merge(requestOptions)); | |
return super.request(request, options) | |
.map(res => res.json()) | |
.catch(this.errorHandler); | |
}); | |
} | |
private errorHandler(errorResponse: Response): Observable<any> | ErrorObservable { | |
if (errorResponse.status === 401) { | |
console.log('redirecting to login'); | |
window.location.href = '/login'; | |
return Observable.empty(); | |
} | |
// If it's a serious problem we toast it, so the user knows | |
if (errorResponse.status === 500) { | |
// this.toastManager.error('Servern returnerade ett 500 fel, någonting är väldigt galet, kontakta digiPlant'); | |
} | |
console.error(errorResponse); | |
return Observable.throw(errorResponse.text().length > 0 ? errorResponse.json() : { status: 'error' }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment