Skip to content

Commit 7d01373

Browse files
change:register, login, authenticated. Add: logout component, logout routes
1 parent 15031be commit 7d01373

13 files changed

+93
-31
lines changed

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
# Angular JWT Authentication System
22

3-
## Screenshots
4-
53
<div align="center">
6-
<img src="./screenshot/login.png" alt="Angular Login Page" width="300" style="margin-right: auto">
7-
<img src="./screenshot/register.png" alt="Angular Registration Page" width="300">
4+
<h3 align="center">Demo</h3>
5+
<img src="./screenshot/login-angular-screenshot.gif" alt="Angular Login Page">
86
</div>
97

108
## Overview
4.85 MB
Loading

screenshot/login.png

-44 KB
Binary file not shown.

screenshot/register.png

-46.6 KB
Binary file not shown.

src/app/app-routing.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import {LoginComponent} from "./component/login/login.component";
44
import {RegisterComponent} from "./component/register/register.component";
55
import {AuthenticatedComponent} from "./component/authenticated/authenticated.component";
66
import {AuthGuard} from "./guards/auth.guard";
7+
import {LogoutComponent} from "./component/logout.component";
78

89
const routes: Routes = [
910
{ path: 'login', component: LoginComponent, data: { title: 'Login' } },
1011
{ path: 'signup', component: RegisterComponent, data: { title: 'Register' } },
11-
{ path: 'dashboard', component: AuthenticatedComponent, data: { title: 'Dashboard' } , canActivate: [AuthGuard]}
12+
{ path: 'dashboard', component: AuthenticatedComponent, data: { title: 'Dashboard' }, canActivate: [AuthGuard]},
13+
{ path: 'logout', component: LogoutComponent, canActivate: [AuthGuard] },
1214
];
1315

1416
@NgModule({

src/app/app.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ import {ToastComponent} from "./component/toast/toast.component";
99
import {RegisterComponent} from "./component/register/register.component";
1010
import {LoginComponent} from "./component/login/login.component";
1111
import {WithCredentialInterceptor} from "./interceptors/with-credential.interceptor";
12+
import {LogoutComponent} from "./component/logout.component";
1213

1314
@NgModule({
1415
declarations: [
1516
AppComponent,
1617
LoginComponent,
1718
RegisterComponent,
1819
ToastComponent,
19-
AuthenticatedComponent
20+
AuthenticatedComponent,
21+
LogoutComponent,
2022
],
2123
imports: [
2224
BrowserModule,
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<div class="hero">
22
<div class="welcome">
33
<h3 class="welcome-heading">WELCOME</h3>
4-
<h1 class="welcome-title mt-3">Mr. </h1>
4+
<h1 class="welcome-title mt-3">Mr. {{ authenticatedUser?.firstName }} {{ authenticatedUser?.lastName }}</h1>
55
<h2 class="welcome-subtitle">This is an example of a JWT authentication system in Angular, showcasing the implementation and security features.</h2>
6-
<br />
6+
<div class="d-flex justify-content-center register">
7+
<p class="">You can test the logout <a (click)="logout()" class="cursor-pointer">Here!</a></p>
8+
</div>
79
</div>
810
</div>
Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
1-
import { Component } from '@angular/core';
1+
import { Component, OnInit } from '@angular/core';
2+
import { Router } from '@angular/router';
3+
import {AuthService} from "../../services/auth.service";
4+
25

36
@Component({
47
selector: 'app-authenticated',
58
templateUrl: './authenticated.component.html',
69
styleUrls: ['./authenticated.component.css']
710
})
8-
export class AuthenticatedComponent {
11+
export class AuthenticatedComponent implements OnInit {
12+
authenticatedUser: any; // Declare a variable to store authenticated user details
13+
14+
constructor(private authService: AuthService, private router: Router) {}
15+
16+
ngOnInit(): void {
17+
this.authService.getAuthenticatedUser().subscribe(
18+
(user) => {
19+
this.authenticatedUser = user;
20+
},
21+
(error) => {
22+
console.error('Error fetching authenticated user:', error);
23+
}
24+
);
25+
}
926

27+
logout() {
28+
this.router.navigate(['/logout']);
29+
}
1030
}

src/app/component/logout.component.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// logout.component.ts
2+
import { Component } from '@angular/core';
3+
import {AuthService} from "../services/auth.service";
4+
import {Router} from "@angular/router";
5+
6+
7+
@Component({
8+
template: '',
9+
})
10+
export class LogoutComponent {
11+
constructor(private authService: AuthService, private router: Router) {
12+
this.authService.logout().subscribe({
13+
next : () => {
14+
this.router.navigate(['/login']);
15+
},
16+
error : (error) => {
17+
console.error('Logout error:', error);
18+
}
19+
});
20+
}
21+
}

src/app/component/register/register.component.html

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,26 @@ <h2 class="my-1 auth-form-title"><strong>Sign Up</strong></h2>
1414
<div class="input-group-addon">
1515
<i class="material-icons">person</i>
1616
</div>
17-
<input type="text" class="form-control" formControlName="firstname">
17+
<input type="text" class="form-control" formControlName="firstName">
1818
<!-- Validation messages -->
1919
</div>
20-
<div *ngIf="f['firstname'].touched && f['firstname'].invalid">
21-
<small class="text-danger" *ngIf="f['firstname'].errors?.['required']">First name is required</small>
22-
<small class="text-danger" *ngIf="f['firstname'].errors?.['minlength']">First name must be at least 2 characters</small>
20+
<div *ngIf="f['firstName'].touched && f['firstName'].invalid">
21+
<small class="text-danger" *ngIf="f['firstName'].errors?.['required']">First name is required</small>
22+
<small class="text-danger" *ngIf="f['firstName'].errors?.['minlength']">First name must be at least 2 characters</small>
2323
</div>
2424
</div>
2525
<div class="form-group col-md-6">
2626
<label>Last Name</label>
2727
<div class="input-group input-group--inline">
2828
<div class="input-group-addon">
29-
<i class="material-icons">person</i>
29+
<i class="material-icons">face</i>
3030
</div>
31-
<input type="text" class="form-control" formControlName="lastname">
31+
<input type="text" class="form-control" formControlName="lastName">
3232
<!-- Validation messages -->
3333
</div>
34-
<div *ngIf="f['lastname'].touched && f['lastname'].invalid">
35-
<small class="text-danger" *ngIf="f['lastname'].errors?.['required']">Last name is required</small>
36-
<small class="text-danger" *ngIf="f['lastname'].errors?.['minlength']">Last name must be at least 2 characters</small>
34+
<div *ngIf="f['lastName'].touched && f['lastName'].invalid">
35+
<small class="text-danger" *ngIf="f['lastName'].errors?.['required']">Last name is required</small>
36+
<small class="text-danger" *ngIf="f['lastName'].errors?.['minlength']">Last name must be at least 2 characters</small>
3737
</div>
3838
</div>
3939
</div>
@@ -60,6 +60,19 @@ <h2 class="my-1 auth-form-title"><strong>Sign Up</strong></h2>
6060
<small class="text-danger" *ngIf="f['email'].errors?.['email']">Please enter a valid email</small>
6161
</div>
6262
</div>
63+
<div class="form-group">
64+
<label>Username</label>
65+
<div class="input-group input-group--inline">
66+
<div class="input-group-addon">
67+
<i class="material-icons">account_circle</i>
68+
</div>
69+
<input type="text" class="form-control" formControlName="username">
70+
</div>
71+
<div *ngIf="f['username'].touched && f['username'].invalid">
72+
<small class="text-danger" *ngIf="f['username'].errors?.['required']">Username is required</small>
73+
<small class="text-danger" *ngIf="f['username'].errors?.['email']">Last name must be at least 5 characters</small>
74+
</div>
75+
</div>
6376
<div class="form-group">
6477
<label>Password</label>
6578
<div class="input-group input-group--inline">

src/app/component/register/register.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ export class RegisterComponent implements OnInit {
1919
constructor(private authService: AuthService, private router: Router) {
2020
// Initialize the registration form with form controls
2121
this.registerForm = new FormGroup({
22-
firstname: new FormControl('', [Validators.required, Validators.minLength(2)]),
23-
lastname: new FormControl('', [Validators.required, Validators.minLength(2)]),
22+
firstName: new FormControl('', [Validators.required, Validators.minLength(2)]),
23+
lastName: new FormControl('', [Validators.minLength(2)]),
24+
username: new FormControl('', [Validators.required, Validators.minLength(5)]),
2425
company: new FormControl(''),
2526
email: new FormControl('', [Validators.required, Validators.email]),
2627
password: new FormControl('', [Validators.required, Validators.minLength(6)])

src/app/services/auth.service.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ import { Observable } from 'rxjs';
66
providedIn: 'root'
77
})
88
export class AuthService {
9-
private loginUrl = 'http://yourapi.com/login';
10-
private registerUrl = 'http://yourapi.com/register';
11-
private logoutUrl = 'http://yourapi.com/logout';
12-
private userUrl = 'http://yourapi.com/user';
9+
private baseUrl = 'http://localhost:3000/api/auth';
10+
11+
private loginUrl = `${this.baseUrl}/login`;
12+
private registerUrl = `${this.baseUrl}/register`;
13+
private logoutUrl = `${this.baseUrl}/logout`;
14+
private userUrl = `${this.baseUrl}/profile`;
1315

1416
constructor(private http: HttpClient) { }
1517

1618
login(credentials: { username: string, password: string }): Observable<any> {
1719
return this.http.post(this.loginUrl, credentials);
1820
}
1921

20-
register(data: { firstname: string, lastname: string, company: string, email: string, password: string }): Observable<any> {
22+
register(data: { firstName: string, lastName: string, company: string, email: string, username: string, password: string }): Observable<any> {
2123
return this.http.post(this.registerUrl, data);
2224
}
2325

src/styles.css

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* Common Styles */
21
.full-page-container {
32
display: flex;
43
justify-content: center;
@@ -10,7 +9,6 @@
109
}
1110

1211

13-
/* Form Styles */
1412
input.form-control {
1513
border: 1px solid #ced4da;
1614
}
@@ -38,7 +36,7 @@ input.form-control:focus {
3836
align-items: center;
3937
}
4038

41-
/* Input Group Styles */
39+
4240
.input-group--inline {
4341
position: relative;
4442
}
@@ -71,7 +69,10 @@ label {
7169
z-index: auto;
7270
}
7371

74-
/* Register Styles */
72+
.cursor-pointer {
73+
cursor: pointer;
74+
}
75+
7576
.register {
7677
font-size: 0.9em;
7778
color: #fff;
@@ -89,7 +90,7 @@ label {
8990
text-decoration: underline;
9091
}
9192

92-
/* Authentication Form Styles */
93+
9394
.auth-form-title {
9495
font-size: 2em;
9596
color: #fff;

0 commit comments

Comments
 (0)