added authentication
This commit is contained in:
parent
9e2720ae88
commit
23d22b00e5
@ -1,9 +1,12 @@
|
||||
import { AuthGuard } from './auth/auth.guard';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', loadChildren: () => import('./subject/subject.module').then(m => m.SubjectModule) }
|
||||
{ path: '', redirectTo: 'user', pathMatch: 'full' },
|
||||
{ path: 'subject', loadChildren: () => import('./subject/subject.module').then(m => m.SubjectModule), canActivate: [AuthGuard] },
|
||||
{ path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { AuthIntercpetor } from './auth/auth.interceptor';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -16,7 +17,11 @@ import { HttpClientModule } from '@angular/common/http';
|
||||
BrowserAnimationsModule,
|
||||
HttpClientModule
|
||||
],
|
||||
providers: [],
|
||||
providers: [{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: AuthIntercpetor,
|
||||
multi: true
|
||||
}],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
16
src/app/auth/auth.guard.spec.ts
Normal file
16
src/app/auth/auth.guard.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthGuard } from './auth.guard';
|
||||
|
||||
describe('AuthGuard', () => {
|
||||
let guard: AuthGuard;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
guard = TestBed.inject(AuthGuard);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(guard).toBeTruthy();
|
||||
});
|
||||
});
|
21
src/app/auth/auth.guard.ts
Normal file
21
src/app/auth/auth.guard.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
||||
canActivate(
|
||||
next: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot): boolean {
|
||||
if (localStorage.getItem('token') !== null) {
|
||||
return true;
|
||||
} else {
|
||||
this.router.navigateByUrl('/user');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
32
src/app/auth/auth.interceptor.ts
Normal file
32
src/app/auth/auth.interceptor.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Router } from '@angular/router';
|
||||
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { tap } from "rxjs/operators";
|
||||
|
||||
@Injectable()
|
||||
export class AuthIntercpetor implements HttpInterceptor {
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
if (localStorage.getItem('token') !== null) {
|
||||
const request = req.clone({
|
||||
headers: req.headers.set('Authorization', 'Bearer ' + localStorage.getItem('token'))
|
||||
});
|
||||
return next.handle(request).pipe(tap(
|
||||
() => {},
|
||||
err => {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('userId');
|
||||
localStorage.removeItem('userName');
|
||||
localStorage.removeItem('fullName');
|
||||
this.router.navigateByUrl('/user');
|
||||
}
|
||||
));
|
||||
} else {
|
||||
return next.handle(req.clone());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
<div class="login-form-container d-flex justify-content-center">
|
||||
<div class="d-flex flex-column">
|
||||
<form [formGroup]="loginForm" class="login-form d-flex flex-column mt-5">
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Username</mat-label>
|
||||
<input matInput formControlName="userName" />
|
||||
@ -8,11 +9,13 @@
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Password</mat-label>
|
||||
<input matInput formControlName="password" />
|
||||
<input matInput formControlName="password" type="password" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="mt-4">
|
||||
<button (click)="onLoginUser()" class="btn btn-primary">Save</button>
|
||||
<button (click)="onLoginUser()" class="btn btn-primary">Sign in</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<a routerLink="/user/register">Registration</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,9 +30,12 @@ export class LoginComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
onRegisterUser(): void {
|
||||
onLoginUser(): void {
|
||||
this.userSerice.login(this.loginForm.value).subscribe((auth: Auth) => {
|
||||
localStorage.setItem('token', auth.token);
|
||||
localStorage.setItem('userId', auth.user.id);
|
||||
localStorage.setItem('userName', auth.user.userName);
|
||||
localStorage.setItem('fullName', auth.user.fullName);
|
||||
this.router.navigateByUrl('/subjects');
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<div class="register-form-container d-flex justify-content-center">
|
||||
<div class="d-flex flex-column">
|
||||
<form [formGroup]="registerForm" class="register-form d-flex flex-column mt-5">
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Username</mat-label>
|
||||
<input matInput formControlName="userName" />
|
||||
@ -11,19 +12,31 @@
|
||||
<input matInput formControlName="fullName" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Password</mat-label>
|
||||
<input matInput formControlName="password" />
|
||||
</mat-form-field>
|
||||
<div formGroupName="passwordForm" class="d-flex flex-column">
|
||||
<mat-form-field>
|
||||
<mat-label>Password</mat-label>
|
||||
<input matInput formControlName="password" type="password" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Repeated password</mat-label>
|
||||
<input matInput formControlName="repeatedPassword" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>Repeated password</mat-label>
|
||||
<input matInput formControlName="repeatedPassword" type="password" />
|
||||
</mat-form-field>
|
||||
|
||||
<div style="color:#ff7355" *ngIf="registerForm.get(['passwordForm', 'password']).value != registerForm.get(['passwordForm', 'repeatedPassword']).value && registerForm.get(['passwordForm', 'repeatedPassword']).value != null">
|
||||
Password does not match
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button (click)="onRegisterUser()" class="btn btn-primary">Save</button>
|
||||
<button [disabled]="registerForm.invalid"
|
||||
(click)="onRegisterUser()"
|
||||
class="btn btn-primary">
|
||||
Sign up
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<a routerLink="/">Back to login page</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { UserService } from './../../services/user.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
||||
import { FormGroup, FormControl, Validators, AbstractControl } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { User } from '../../interfaces/user.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-register',
|
||||
@ -24,14 +25,27 @@ export class RegisterComponent implements OnInit {
|
||||
return new FormGroup({
|
||||
userName: new FormControl('', Validators.required),
|
||||
fullName: new FormControl('', Validators.required),
|
||||
password: new FormControl('', Validators.required),
|
||||
repeatedPassword: new FormControl('', Validators.required)
|
||||
passwordForm: new FormGroup({
|
||||
password: new FormControl('', Validators.required),
|
||||
repeatedPassword: new FormControl('', Validators.required)
|
||||
}, this.passwordValidator)
|
||||
});
|
||||
}
|
||||
|
||||
private passwordValidator(form: AbstractControl): { invalid: boolean } {
|
||||
if (form.get('password').value !== form.get('repeatedPassword').value) {
|
||||
return {invalid: true};
|
||||
}
|
||||
}
|
||||
|
||||
onRegisterUser(): void {
|
||||
this.userSerice.register(this.registerForm.value).subscribe(() => {
|
||||
this.router.navigateByUrl('/subjects');
|
||||
const user: User = {
|
||||
userName: this.registerForm.get('userName').value,
|
||||
fullName: this.registerForm.get('fullName').value,
|
||||
password: this.registerForm.get(['passwordForm', 'password']).value
|
||||
}
|
||||
this.userSerice.register(user).subscribe(() => {
|
||||
this.router.navigateByUrl('/user/login');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { User } from './user.interface';
|
||||
export interface Auth {
|
||||
token: string;
|
||||
user: User;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export interface User {
|
||||
id?: number;
|
||||
id?: string;
|
||||
userName: string;
|
||||
fullName: string;
|
||||
password?: string;
|
||||
|
@ -5,7 +5,8 @@ import { RegisterComponent } from './components/register/register.component';
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: LoginComponent },
|
||||
{ path: '', redirectTo: 'login', pathMatch: 'full'},
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: 'register', component: RegisterComponent }
|
||||
];
|
||||
|
||||
@ -13,4 +14,4 @@ const routes: Routes = [
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class SubjectRoutingModule { }
|
||||
export class UserRoutingModule { }
|
||||
|
@ -1,14 +1,22 @@
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RegisterComponent } from './components/register/register.component';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { UserRoutingModule } from './user-routing.module';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [RegisterComponent, LoginComponent],
|
||||
imports: [
|
||||
CommonModule
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
UserRoutingModule
|
||||
]
|
||||
})
|
||||
export class UserModule { }
|
||||
|
Loading…
Reference in New Issue
Block a user