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 8d2571a

Browse files
committed
first commit
1 parent ca165cc commit 8d2571a

Some content is hidden

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

47 files changed

+1132
-501
lines changed

‎README.md

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,71 @@
1-
# Angular15RefreshToken
1+
# Angular 15 JWT Refresh Token example with Http Interceptor
22

3-
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.0.3.
3+
Implementing Angular 15 Refresh Token before Expiration with Http Interceptor and JWT.
4+
You can take a look at following flow to have an overview of Requests and Responses that Angular 15 Client will make or receive.
45

5-
## Development server
6+
## Angular JWT Refresh Token Flow
7+
![angular-15-refresh-token-jwt-example](angular-15-refresh-token-jwt-example.png)
68

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.
9+
For more detail, please visit:
10+
> [Angular 15 Refresh Token with Interceptor and JWT example](https://www.bezkoder.com/angular-15-refresh-token/)
811
9-
## Code scaffolding
12+
> [Angular 15 JWT Authentication & Authorization with Web API example](https://www.bezkoder.com/angular-15-jwt-auth/)
1013
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`.
14+
## Fullstack
15+
> [Angular 15 + Spring Boot: JWT Authentication and Authorization example](https://www.bezkoder.com/angular-15-spring-boot-jwt-auth/)
1216
13-
## Build
17+
> [Angular 15 + Node.js Express: JWT Authentication and Authorization example](https://www.bezkoder.com/node-js-angular-15-jwt-auth/)
1418
15-
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
19+
Run `ng serve --port 8081` for a dev server. Navigate to `http://localhost:8081/`.
1620

17-
## Running unit tests
21+
## More practice
22+
> [Angular 15 CRUD example with Web API](https://www.bezkoder.com/angular-15-crud-example/)
1823
19-
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
24+
> [Angular 15 Pagination example](https://www.bezkoder.com/angular-15-pagination-ngx/)
2025
21-
## Running end-to-end tests
26+
> [Angular 15 File upload example with Progress bar](https://www.bezkoder.com/angular-15-file-upload/)
2227
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.
28+
Fullstack with Node:
29+
> [Angular 15 + Node Express + MySQL example](https://www.bezkoder.com/angular-15-node-js-express-mysql/)
2430
25-
## Further help
31+
> [Angular 15 + Node Express + PostgreSQL example](https://www.bezkoder.com/angular-15-node-js-express-postgresql/)
2632
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.
33+
> [Angular 15 + Node Express + MongoDB example](https://www.bezkoder.com/angular-15-node-js-express-mongodb/)
34+
35+
> [Angular 15 + Node Express: File upload example](https://www.bezkoder.com/angular-15-node-express-file-upload/)
36+
37+
> [Angular 15 + Node.js Express: JWT Authentication and Authorization example](https://www.bezkoder.com/node-js-angular-15-jwt-auth/)
38+
39+
Fullstack with Spring Boot:
40+
> [Angular 15 + Spring Boot example](https://www.bezkoder.com/spring-boot-angular-15-crud/)
41+
42+
> [Angular 15 + Spring Boot + MySQL example](https://www.bezkoder.com/spring-boot-angular-15-mysql/)
43+
44+
> [Angular 15 + Spring Boot + PostgreSQL example](https://www.bezkoder.com/spring-boot-angular-15-postgresql/)
45+
46+
> [Angular 15 + Spring Boot + MongoDB example](https://www.bezkoder.com/spring-boot-angular-15-mongodb/)
47+
48+
> [Angular 15 + Spring Boot: File upload example](https://www.bezkoder.com/angular-15-spring-boot-file-upload/)
49+
50+
> [Angular 15 + Spring Boot: JWT Authentication and Authorization example](https://www.bezkoder.com/angular-15-spring-boot-jwt-auth/)
51+
52+
Fullstack with Django:
53+
> [Angular + Django example](https://www.bezkoder.com/django-angular-13-crud-rest-framework/)
54+
55+
> [Angular + Django + MySQL](https://www.bezkoder.com/django-angular-mysql/)
56+
57+
> [Angular + Django + PostgreSQL](https://www.bezkoder.com/django-angular-postgresql/)
58+
59+
> [Angular + Django + MongoDB](https://www.bezkoder.com/django-angular-mongodb/)
60+
61+
Serverless with Firebase:
62+
> [Angular 15 Firebase CRUD with Realtime DataBase](https://www.bezkoder.com/angular-15-firebase-crud/)
63+
64+
> [Angular 15 Firestore CRUD example](https://www.bezkoder.com/angular-15-firestore-crud/)
65+
66+
> [Angular 15 Firebase Storage: File Upload/Display/Delete example](https://www.bezkoder.com/angular-15-firebase-storage/)
67+
68+
Integration (run back-end & front-end on same server/port)
69+
> [How to integrate Angular with Node Restful Services](https://www.bezkoder.com/integrate-angular-12-node-js/)
70+
71+
> [How to Integrate Angular with Spring Boot Rest API](https://www.bezkoder.com/integrate-angular-12-spring-boot/)
33.8 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: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Injectable } from '@angular/core';
2+
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS, HttpErrorResponse } from '@angular/common/http';
3+
4+
import { StorageService } from '../_services/storage.service';
5+
import { AuthService } from '../_services/auth.service';
6+
7+
import { Observable, throwError } from 'rxjs';
8+
import { catchError, switchMap } from 'rxjs/operators';
9+
10+
import { EventBusService } from '../_shared/event-bus.service';
11+
import { EventData } from '../_shared/event.class';
12+
13+
@Injectable()
14+
export class HttpRequestInterceptor implements HttpInterceptor {
15+
private isRefreshing = false;
16+
17+
constructor(
18+
private storageService: StorageService,
19+
private authService: AuthService,
20+
private eventBusService: EventBusService
21+
) {}
22+
23+
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
24+
req = req.clone({
25+
withCredentials: true,
26+
});
27+
28+
return next.handle(req).pipe(
29+
catchError((error) => {
30+
if (
31+
error instanceof HttpErrorResponse &&
32+
!req.url.includes('auth/signin') &&
33+
error.status === 401
34+
) {
35+
return this.handle401Error(req, next);
36+
}
37+
38+
return throwError(() => error);
39+
})
40+
);
41+
}
42+
43+
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
44+
if (!this.isRefreshing) {
45+
this.isRefreshing = true;
46+
47+
if (this.storageService.isLoggedIn()) {
48+
return this.authService.refreshToken().pipe(
49+
switchMap(() => {
50+
this.isRefreshing = false;
51+
52+
return next.handle(request);
53+
}),
54+
catchError((error) => {
55+
this.isRefreshing = false;
56+
57+
if (error.status == '403') {
58+
this.eventBusService.emit(new EventData('logout', null));
59+
}
60+
61+
return throwError(() => error);
62+
})
63+
);
64+
}
65+
}
66+
67+
return next.handle(request);
68+
}
69+
}
70+
71+
export const httpInterceptorProviders = [
72+
{ provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true },
73+
];

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

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: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
44+
refreshToken() {
45+
return this.http.post(AUTH_API + 'refreshtoken', { }, httpOptions);
46+
}
47+
}
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+
}

‎src/app/_services/user.service.spec.ts

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 { UserService } from './user.service';
4+
5+
describe('UserService', () => {
6+
let service: UserService;
7+
8+
beforeEach(() => {
9+
TestBed.configureTestingModule({});
10+
service = TestBed.inject(UserService);
11+
});
12+
13+
it('should be created', () => {
14+
expect(service).toBeTruthy();
15+
});
16+
});

0 commit comments

Comments
(0)

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