Skip to content

Commit d39bd1d

Browse files
committed
Add csrf based configurations & http interceptor.
1 parent 7b38cd2 commit d39bd1d

9 files changed

+122
-6
lines changed

app/controllers/HomeController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ public Result appSummary() {
2626
JsonNode jsonNode = Json.toJson(new AppSummary("Java Play Angular Seed"));
2727
return ok(jsonNode).as("application/json");
2828
}
29+
30+
public Result postTest() {
31+
JsonNode jsonNode = Json.toJson(new AppSummary("Post Request Test => Data Sending Success"));
32+
return ok(jsonNode).as("application/json");
33+
}
2934
}

conf/application.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ play.filters {
246246
# or body of every form submitted, and also gets placed in the users session.
247247
# Play then verifies that both tokens are present and match.
248248
csrf {
249+
cookie.name = "Csrf-Token"
250+
249251
# Sets the cookie to be sent only over HTTPS
250252
#cookie.secure = true
251253

conf/routes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ GET /api/summary controllers.HomeController.appSummary
1010

1111
# Serve static assets under public directory
1212
GET /*file controllers.FrontendController.assetOrDefault(file)
13+
14+
# Test post request
15+
POST /api/postTest controllers.HomeController.postTest()

ui/src/app/app.component.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.post-request-test {
2+
padding-top: 1rem;
3+
}

ui/src/app/app.component.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ <h3>
2121
</a>
2222
</h3>
2323
</div>
24+
25+
<div class="post-request-test">
26+
<h3>Test Post Request</h3>
27+
<button (click)="postData()">ClickMe :)</button>
28+
<h5>Response: {{postRequestResponse}}</h5>
29+
</div>
2430
</div>

ui/src/app/app.component.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Component } from '@angular/core';
2+
23
import { AppService } from './app.service';
34

45
@Component({
@@ -8,10 +9,20 @@ import { AppService } from './app.service';
89
})
910
export class AppComponent {
1011
title: string;
12+
postRequestResponse: string;
1113

1214
constructor(private appService: AppService) {
1315
this.appService.getWelcomeMessage().subscribe((data: any) => {
1416
this.title = data.content;
1517
});
1618
}
19+
20+
/**
21+
* This method is used to test the post request
22+
*/
23+
public postData(): void {
24+
this.appService.sendData().subscribe((data: any) => {
25+
this.postRequestResponse = data.content;
26+
});
27+
}
1728
}

ui/src/app/app.module.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import { BrowserModule } from '@angular/platform-browser';
22
import { NgModule } from '@angular/core';
33
import { RouterModule, Routes } from '@angular/router';
4+
import { HTTP_INTERCEPTORS, HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';
45

56
import { AppComponent } from './app.component';
6-
import { AppService } from './app.service';
7-
import { HttpClientModule } from '@angular/common/http';
87
import { RouteExampleComponent } from './route-example/route-example.component';
98

9+
import { AppService } from './app.service';
10+
import { AppHttpInterceptorService } from './http-interceptor.service';
11+
1012
const routes: Routes = [
1113
{
1214
path: 'java',
1315
component: RouteExampleComponent,
14-
data: {technology: 'Java'}
16+
data: { technology: 'Java' }
1517
},
1618
{
1719
path: 'play',
1820
component: RouteExampleComponent,
19-
data: {technology: 'Play'}
21+
data: { technology: 'Play' }
2022
},
2123
{
2224
path: 'angular',
2325
component: RouteExampleComponent,
24-
data: {technology: 'Angular'}
26+
data: { technology: 'Angular' }
2527
},
2628
{
2729
path: '**',
@@ -38,9 +40,20 @@ const routes: Routes = [
3840
imports: [
3941
BrowserModule,
4042
HttpClientModule,
43+
HttpClientXsrfModule.withOptions({
44+
cookieName: 'Csrf-Token',
45+
headerName: 'Csrf-Token',
46+
}),
4147
RouterModule.forRoot(routes)
4248
],
43-
providers: [AppService],
49+
providers: [
50+
AppService,
51+
{
52+
multi: true,
53+
provide: HTTP_INTERCEPTORS,
54+
useClass: AppHttpInterceptorService
55+
}
56+
],
4457
bootstrap: [AppComponent]
4558
})
4659
export class AppModule {

ui/src/app/app.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Injectable } from '@angular/core';
22
import { HttpClient } from '@angular/common/http';
3+
34
import { map } from 'rxjs/operators';
5+
import { Observable } from 'rxjs/index';
46

57
/**
68
* Class representing application service.
@@ -10,6 +12,7 @@ import { map } from 'rxjs/operators';
1012
@Injectable()
1113
export class AppService {
1214
private serviceUrl = '/api/summary';
15+
private dataPostTestUrl = '/api/postTest';
1316

1417
constructor(private http: HttpClient) {
1518
}
@@ -22,4 +25,11 @@ export class AppService {
2225
map(response => response)
2326
);
2427
}
28+
29+
/**
30+
* Makes a http post request to send some data to backend & get response.
31+
*/
32+
public sendData(): Observable<any> {
33+
return this.http.post(this.dataPostTestUrl, {});
34+
}
2535
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
2+
import { Injectable } from '@angular/core';
3+
4+
import { Observable, throwError } from 'rxjs';
5+
import { catchError } from 'rxjs/operators';
6+
7+
/**
8+
* Module class for application http interceptor.
9+
* @implements HttpInterceptor
10+
* @class AppHttpInterceptorService.
11+
*/
12+
@Injectable()
13+
export class AppHttpInterceptorService implements HttpInterceptor {
14+
15+
constructor() {
16+
}
17+
18+
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
19+
return next
20+
.handle(req)
21+
.pipe(catchError(err => {
22+
if (err instanceof HttpErrorResponse) {
23+
this.onError(err);
24+
}
25+
return throwError(err);
26+
}));
27+
}
28+
29+
/**
30+
* Handle http errors.
31+
* @param response - ErrorResponse.
32+
*/
33+
private onError(response: HttpErrorResponse): void {
34+
const clientErrorMessage = this.handleClientSideError(response.status);
35+
if (clientErrorMessage) {
36+
// show client side error
37+
console.log(clientErrorMessage);
38+
return;
39+
}
40+
41+
const serverErrorMessage = this.handleServerError(response.error);
42+
if (serverErrorMessage) {
43+
// show server error
44+
console.log(serverErrorMessage);
45+
}
46+
}
47+
48+
private handleClientSideError(status: number): string {
49+
switch (status) {
50+
case 0:
51+
return 'NO INTERNET CONNECTION';
52+
case 404:
53+
return 'REQUEST FAILURE';
54+
default:
55+
return;
56+
}
57+
}
58+
59+
private handleServerError(errorResponse: any): string {
60+
// handle server error
61+
return '';
62+
}
63+
}

0 commit comments

Comments
 (0)