Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 719f679

Browse files
committed
first commit
1 parent b4629cb commit 719f679

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1130
-501
lines changed

‎README.md‎

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,95 @@
1-
# Angular15JwtAuth
1+
# Angular 15 JWT Authentication & Authorization example with Rest API
22

3-
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.0.3.
3+
Build Angular 15 JWT Authentication & Authorization example with Rest Api, HttpOnly Cookie and JWT (including HttpInterceptor, Router & Form Validation).
4+
- JWT Authentication Flow for User Registration (Signup) & User Login
5+
- Project Structure with HttpInterceptor, Router
6+
- Way to implement HttpInterceptor
7+
- How to store JWT token in HttpOnly Cookie
8+
- Creating Login, Signup Components with Form Validation
9+
- Angular Components for accessing protected Resources
10+
- How to add a dynamic Navigation Bar to Angular App
11+
- Working with Browser Session Storage
412

5-
## Development server
13+
## Flow for User Registration and User Login
14+
For JWT – Token based Authentication with Rest API, we’re gonna call 2 endpoints:
15+
- POST `api/auth/signup` for User Registration
16+
- POST `api/auth/signin` for User Login
17+
- POST `api/auth/signout` for User Logout
618

7-
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
19+
You can take a look at following flow to have an overview of Requests and Responses that Angular 15 JWT Authentication & Authorization Client will make or receive.
820

9-
## Code scaffolding
21+
![angular-15-jwt-authentication-authorization-flow](angular-15-jwt-authentication-authorization-flow.png)
1022

11-
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
23+
## Angular JWT App Diagram with Router and HttpInterceptor
24+
![angular-15-jwt-authentication](angular-15-jwt-authentication.png)
1225

13-
## Build
26+
For more detail, please visit the tutorial:
27+
> [Angular 15 JWT Authentication & Authorization with Web API example](https://www.bezkoder.com/angular-15-jwt-auth/)
1428
15-
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
29+
> [Angular Logout when Token is expired](https://www.bezkoder.com/logout-when-token-expired-angular-15/)
1630
17-
## Running unit tests
31+
> [Angular Refresh Token with Interceptor and JWT example](https://www.bezkoder.com/angular-15-refresh-token/)
1832
19-
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
33+
## With Spring Boot back-end
2034

21-
## Running end-to-end tests
35+
> [Angular 15 + Spring Boot: JWT Authentication and Authorization example](https://www.bezkoder.com/angular-15-spring-boot-jwt-auth/)
2236
23-
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
37+
## With Node.js Express back-end
2438

25-
## Further help
39+
> [Angular 15 + Node.js Express: JWT Authentication and Authorization example](https://www.bezkoder.com/node-js-angular-15-jwt-auth/)
2640
27-
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
41+
Run `ng serve --port 8081` for a dev server. Navigate to `http://localhost:8081/`.
42+
43+
## More practice
44+
> [Angular 15 CRUD example with Rest API](https://www.bezkoder.com/angular-15-crud-example/)
45+
46+
> [Angular 15 Pagination example](https://www.bezkoder.com/angular-15-pagination-ngx/)
47+
48+
> [Angular 15 File upload example with Progress bar](https://www.bezkoder.com/angular-15-file-upload/)
49+
50+
> [Angular 15 Form Validation example](https://www.bezkoder.com/angular-15-form-validation/)
51+
52+
Fullstack with Node:
53+
> [Angular 15 + Node Express + MySQL example](https://www.bezkoder.com/angular-15-node-js-express-mysql/)
54+
55+
> [Angular 15 + Node Express + PostgreSQL example](https://www.bezkoder.com/angular-15-node-js-express-postgresql/)
56+
57+
> [Angular 15 + Node Express + MongoDB example](https://www.bezkoder.com/angular-15-node-js-express-mongodb/)
58+
59+
> [Angular 15 + Node Express: File upload example](https://www.bezkoder.com/angular-15-node-express-file-upload/)
60+
61+
> [Angular 15 + Node.js Express: JWT Authentication and Authorization example](https://www.bezkoder.com/node-js-angular-15-jwt-auth/)
62+
63+
Fullstack with Spring Boot:
64+
> [Angular 15 + Spring Boot example](https://www.bezkoder.com/spring-boot-angular-15-crud/)
65+
66+
> [Angular 15 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-15-mysql/)
67+
68+
> [Angular 15 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-15-postgresql/)
69+
70+
> [Angular 15 + Spring Boot + MongoDB example](https://www.bezkoder.com/spring-boot-angular-15-mongodb/)
71+
72+
> [Angular 15 + Spring Boot: File upload example](https://www.bezkoder.com/angular-15-spring-boot-file-upload/)
73+
74+
> [Angular 15 + Spring Boot: JWT Authentication and Authorization example](https://www.bezkoder.com/angular-15-spring-boot-jwt-auth/)
75+
76+
Fullstack with Django:
77+
> [Angular + Django example](https://www.bezkoder.com/django-angular-13-crud-rest-framework/)
78+
79+
> [Angular + Django + MySQL](https://www.bezkoder.com/django-angular-mysql/)
80+
81+
> [Angular + Django + PostgreSQL](https://www.bezkoder.com/django-angular-postgresql/)
82+
83+
> [Angular + Django + MongoDB](https://www.bezkoder.com/django-angular-mongodb/)
84+
85+
Serverless with Firebase:
86+
> [Angular 15 Firebase CRUD with Realtime DataBase](https://www.bezkoder.com/angular-15-firebase-crud/)
87+
88+
> [Angular 15 Firestore CRUD example](https://www.bezkoder.com/angular-15-firestore-crud/)
89+
90+
> [Angular 15 Firebase Storage: File Upload/Display/Delete example](https://www.bezkoder.com/angular-15-firebase-storage/)
91+
92+
Integration (run back-end & front-end on same server/port)
93+
> [How to integrate Angular with Node Restful Services](https://www.bezkoder.com/integrate-angular-12-node-js/)
94+
95+
> [How to Integrate Angular with Spring Boot Rest API](https://www.bezkoder.com/integrate-angular-12-spring-boot/)
34 KB
Loading[フレーム]

‎angular-15-jwt-authentication.png‎

22.6 KB
Loading[フレーム]

‎package-lock.json‎

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@angular/platform-browser": "^15.0.0",
1919
"@angular/platform-browser-dynamic": "^15.0.0",
2020
"@angular/router": "^15.0.0",
21+
"bootstrap": "^4.6.2",
2122
"rxjs": "~7.5.0",
2223
"tslib": "^2.3.0",
2324
"zone.js": "~0.12.0"

‎src/app/_helpers/http.interceptor.ts‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Injectable } from '@angular/core';
2+
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS, HttpErrorResponse } from '@angular/common/http';
3+
import { Observable, throwError } from 'rxjs';
4+
import { catchError } from 'rxjs/operators';
5+
6+
import { StorageService } from '../_services/storage.service';
7+
import { EventBusService } from '../_shared/event-bus.service';
8+
import { EventData } from '../_shared/event.class';
9+
10+
@Injectable()
11+
export class HttpRequestInterceptor implements HttpInterceptor {
12+
private isRefreshing = false;
13+
14+
constructor(private storageService: StorageService, private eventBusService: EventBusService) { }
15+
16+
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
17+
req = req.clone({
18+
withCredentials: true,
19+
});
20+
21+
return next.handle(req).pipe(
22+
catchError((error) => {
23+
if (
24+
error instanceof HttpErrorResponse &&
25+
!req.url.includes('auth/signin') &&
26+
error.status === 401
27+
) {
28+
return this.handle401Error(req, next);
29+
}
30+
31+
return throwError(() => error);
32+
})
33+
);
34+
}
35+
36+
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
37+
if (!this.isRefreshing) {
38+
this.isRefreshing = true;
39+
40+
if (this.storageService.isLoggedIn()) {
41+
this.eventBusService.emit(new EventData('logout', null));
42+
}
43+
}
44+
45+
return next.handle(request);
46+
}
47+
}
48+
49+
export const httpInterceptorProviders = [
50+
{ provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true },
51+
];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { AuthService } from './auth.service';
4+
5+
describe('AuthService', () => {
6+
let service: AuthService;
7+
8+
beforeEach(() => {
9+
TestBed.configureTestingModule({});
10+
service = TestBed.inject(AuthService);
11+
});
12+
13+
it('should be created', () => {
14+
expect(service).toBeTruthy();
15+
});
16+
});

‎src/app/_services/auth.service.ts‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Injectable } from '@angular/core';
2+
import { HttpClient, HttpHeaders } from '@angular/common/http';
3+
import { Observable } from 'rxjs';
4+
5+
const AUTH_API = 'http://localhost:8080/api/auth/';
6+
7+
const httpOptions = {
8+
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
9+
};
10+
11+
@Injectable({
12+
providedIn: 'root',
13+
})
14+
export class AuthService {
15+
constructor(private http: HttpClient) {}
16+
17+
login(username: string, password: string): Observable<any> {
18+
return this.http.post(
19+
AUTH_API + 'signin',
20+
{
21+
username,
22+
password,
23+
},
24+
httpOptions
25+
);
26+
}
27+
28+
register(username: string, email: string, password: string): Observable<any> {
29+
return this.http.post(
30+
AUTH_API + 'signup',
31+
{
32+
username,
33+
email,
34+
password,
35+
},
36+
httpOptions
37+
);
38+
}
39+
40+
logout(): Observable<any> {
41+
return this.http.post(AUTH_API + 'signout', { }, httpOptions);
42+
}
43+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { StorageService } from './storage.service';
4+
5+
describe('StorageService', () => {
6+
let service: StorageService;
7+
8+
beforeEach(() => {
9+
TestBed.configureTestingModule({});
10+
service = TestBed.inject(StorageService);
11+
});
12+
13+
it('should be created', () => {
14+
expect(service).toBeTruthy();
15+
});
16+
});

‎src/app/_services/storage.service.ts‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Injectable } from '@angular/core';
2+
3+
const USER_KEY = 'auth-user';
4+
5+
@Injectable({
6+
providedIn: 'root'
7+
})
8+
export class StorageService {
9+
constructor() {}
10+
11+
clean(): void {
12+
window.sessionStorage.clear();
13+
}
14+
15+
public saveUser(user: any): void {
16+
window.sessionStorage.removeItem(USER_KEY);
17+
window.sessionStorage.setItem(USER_KEY, JSON.stringify(user));
18+
}
19+
20+
public getUser(): any {
21+
const user = window.sessionStorage.getItem(USER_KEY);
22+
if (user) {
23+
return JSON.parse(user);
24+
}
25+
26+
return {};
27+
}
28+
29+
public isLoggedIn(): boolean {
30+
const user = window.sessionStorage.getItem(USER_KEY);
31+
if (user) {
32+
return true;
33+
}
34+
35+
return false;
36+
}
37+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /