I am using the JWT
token for the authentication and storing that in local storage and now wanted to add CSRF
token with that, is it possible to activate CSRF
just in angular?
As JWT token generate is it possible to generate CSRF
randomly with that and store it?
I am trying to something like below
authentication.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators/map';
import { Router } from '@angular/router';
export interface UserDetails {
_id: string;
email: string;
name: string;
exp: number;
iat: number;
}
interface TokenResponse {
token: string;
}
export interface TokenPayload {
email: string;
password: string;
name?: string;
}
@Injectable()
export class AuthenticationService {
private token: string;
constructor(private http: HttpClient, private router: Router) {}
private saveToken(token: string): void {
localStorage.setItem('mean-token', token);
this.token = token;
}
private getToken(): string {
if (!this.token) {
this.token = localStorage.getItem('mean-token');
}
return this.token;
}
public getUserDetails(): UserDetails {
const token = this.getToken();
let payload;
if (token) {
payload = token.split('.')[1];
payload = window.atob(payload);
return JSON.parse(payload);
} else {
return null;
}
}
public isLoggedIn(): boolean {
const user = this.getUserDetails();
if (user) {
return user.exp > Date.now() / 1000;
} else {
return false;
}
}
private request(method: 'post'|'get', type: 'login'|'register'|'profile', user?: TokenPayload): Observable<any> {
let base;
if (method === 'post') {
base = this.http.post(`/api/${type}`, user);
} else {
base = this.http.get(`/api/${type}`, { headers: { Authorization: `Bearer ${this.getToken()}` }});
}
const request = base.pipe(
map((data: TokenResponse) => {
if (data.token) {
this.saveToken(data.token);
}
return data;
})
);
return request;
}
public register(user: TokenPayload): Observable<any> {
return this.request('post', 'register', user);
}
public login(user: TokenPayload): Observable<any> {
return this.request('post', 'login', user);
}
public profile(): Observable<any> {
return this.request('get', 'profile');
}
public logout(): void {
this.token = '';
window.localStorage.removeItem('mean-token');
this.router.navigateByUrl('/');
}
}
auth.interceptor.ts
import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler, HttpXsrfTokenExtractor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
return next.handle(req);
}
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HttpClientXsrfModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { ProfileComponent } from './profile/profile.component';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { HomeComponent } from './home/home.component';
import { AuthenticationService } from './authentication.service';
import { AuthGuardService } from './auth-guard.service';
import { HttpXsrfInterceptor } from './auth.interceptor';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuardService] }
];
@NgModule({
declarations: [
AppComponent,
ProfileComponent,
LoginComponent,
RegisterComponent,
HomeComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'My-Xsrf-Cookie',
headerName: 'My-Xsrf-Header'
}),
RouterModule.forRoot(routes),
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpXsrfInterceptor, multi: true },
AuthenticationService,
AuthGuardService
],
bootstrap: [AppComponent]
})
export class AppModule { }