Begin by ensuring that you have the Angular CLI installed. If not, install it globally using npm:
npm install -g @angular/cli
Create a new Angular project by running:
ng new fiber-angular-client
cd fiber-angular-client
This command scaffolds a new Angular application named "fiber-angular-client" and navigates into the project directory.
To handle HTTP requests and manage cookies effectively, install the following packages:
npm install @angular/common @angular/forms rxjs ngx-cookie-service
These packages facilitate HTTP communications, form handling, reactive programming, and cookie management within your Angular application.
Create a dedicated service to handle authentication processes such as login, logout, and session verification.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { CookieService } from 'ngx-cookie-service';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private apiUrl = 'http://localhost:3000'; // Replace with your Fiber backend URL
constructor(private http: HttpClient, private cookieService: CookieService) { }
login(username: string, password: string): Observable<any> {
return this.http.post(`${this.apiUrl}/login`, { username, password }, { withCredentials: true });
}
logout(): Observable<any> {
return this.http.post(`${this.apiUrl}/logout`, {}, { withCredentials: true });
}
isLoggedIn(): boolean {
return this.cookieService.check('session');
}
}
Explanation:
login
: Sends user credentials to the Fiber backend's login endpoint.logout
: Initiates a logout request to terminate the session.isLoggedIn
: Checks for the presence of a session cookie to determine authentication status.Generate and implement the login component to capture user credentials:
ng generate component components/login
// src/app/components/login/login.component.ts
import { Component } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
username: string = '';
password: string = '';
loginError: string = '';
constructor(private authService: AuthService, private router: Router) { }
onSubmit(): void {
this.authService.login(this.username, this.password).subscribe(
response => {
console.log('Login successful', response);
this.router.navigate(['/dashboard']);
},
error => {
console.error('Login failed', error);
this.loginError = 'Invalid credentials. Please try again.';
}
);
}
}
<!-- src/app/components/login/login.component.html -->
<div>
<h2 style="color:#cc9900;">Login</h2>
<form (ngSubmit)="onSubmit()">
<div>
<label for="username">Username:</label>
<input id="username" [(ngModel)]="username" name="username" required />
</div>
<div>
<label for="password">Password:</label>
<input id="password" type="password" [(ngModel)]="password" name="password" required />
</div>
<button type="submit">Login</button>
</form>
<div *ngIf="loginError" style="color: red;">
{{ loginError }}
</div>
</div>
Create a dashboard component to display protected information after successful login:
ng generate component components/dashboard
// src/app/components/dashboard/dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
protectedData: any;
errorMessage: string = '';
constructor(private authService: AuthService) { }
ngOnInit(): void {
this.authService.getProtectedData().subscribe(
data => {
this.protectedData = data;
},
error => {
console.error('Error fetching protected data', error);
this.errorMessage = 'Unable to access protected resources.';
}
);
}
}
Dashboard
Protected Information:
{{ protectedData | json }}
{{ errorMessage }}
On the Fiber backend, configure session cookies with security attributes:
// Example Fiber middleware for setting cookies
app.Use(cors.New(cors.Config{
AllowOrigins: "http://localhost:4200",
AllowCredentials: true,
}))
app.Use(sessions.New(sessions.Config{
CookieHTTPOnly: true,
CookieSecure: true,
CookieSameSite: "lax",
}))
Attributes Explained:
HTTPOnly
: Prevents JavaScript from accessing the cookie, mitigating XSS attacks.Secure
: Ensures cookies are only sent over HTTPS.SameSite
: Controls whether cookies are sent with cross-site requests, reducing CSRF risks.Implement route guards to restrict access to authenticated users:
// src/app/guards/auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
Define application routes and apply the authentication guard to protected routes:
// src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './components/login/login.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { AuthGuard } from './guards/auth.guard';
const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Ensure that the AppRoutingModule
is imported in your AppModule
:
// src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { CookieService } from 'ngx-cookie-service';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './components/login/login.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
AppRoutingModule
],
providers: [CookieService],
bootstrap: [AppComponent]
})
export class AppModule { }
Utilize an HTTP interceptor to automatically include credentials with outgoing requests:
// src/app/interceptors/auth.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authReq = req.clone({
withCredentials: true
});
return next.handle(authReq);
}
}
Register the interceptor in your AppModule
:
// src/app/app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './interceptors/auth.interceptor';
@NgModule({
// ...
providers: [
CookieService,
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
],
// ...
})
Ensure that your Fiber backend is correctly configured to handle CORS and allow credentials from your Angular application's origin:
// Example Fiber CORS configuration
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
)
app := fiber.New()
app.Use(cors.New(cors.Config{
AllowOrigins: "http://localhost:4200",
AllowHeaders: "Origin, Content-Type, Accept",
AllowCredentials: true,
}))
This configuration permits your Angular application running on http://localhost:4200
to communicate with the Fiber backend, ensuring that cookies and credentials are properly handled.
Follow these steps to test your Angular client with the Fiber backend:
ng serve
Navigate to http://localhost:4200 in your browser.
Security Practice | Description |
---|---|
HTTP-Only Cookies | Cookies are inaccessible to JavaScript, mitigating XSS attack vectors. |
Secure Cookies | Cookies are only transmitted over HTTPS, preventing interception. |
SameSite Attribute | Controls cross-site request behavior of cookies to prevent CSRF attacks. |
Input Validation | Sanitize and validate all user inputs on both frontend and backend. |
Rate Limiting | Implement rate limiting on authentication endpoints to prevent brute force attacks. |
Session Expiration | Set appropriate session timeouts to reduce the risk of unauthorized access. |
By following this comprehensive guide, you can successfully create an Angular client that integrates seamlessly with a Fiber backend using session-based authentication. This setup ensures secure user authentication, effective session management, and protection of sensitive routes, laying a solid foundation for building scalable and secure web applications.