Chat
Search
Ithy Logo

Creating an Angular Client Based on Fiber's Session Authentication Example

A comprehensive guide to building a secure Angular application with Fiber backend

secure angular fiber integration

Key Takeaways

  • Seamless Integration: Combine Angular's robust frontend capabilities with Fiber's efficient session management for a secure authentication flow.
  • Session Handling: Utilize cookies and Angular services to manage user sessions effectively, ensuring secure access to protected routes.
  • Security Best Practices: Implement HTTP-only cookies, route guards, and proper CORS configurations to safeguard your application against common vulnerabilities.

1. Setting Up the Angular Project

Initializing Your Angular Application

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.

2. Installing Necessary Dependencies

Adding Essential Packages

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.

3. Implementing the Authentication Service

Managing Authentication Logic

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.

4. Creating Authentication Components

Building Login and Dashboard Interfaces

4.1 Login Component

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>

4.2 Dashboard Component

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 }}

5. Managing Sessions and Cookies

Ensuring Secure Session Handling

5.1 Cookie Configuration

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.

5.2 Auth Guard Implementation

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;
    }
  }
}

6. Setting Up Angular Routing

Navigating Between Components

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 { }

7. Protecting HTTP Requests with Interceptors

Ensuring Cookies Are Sent with Requests

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 }
  ],
  // ...
})

8. Handling CORS and Backend Configuration

Configuring Fiber Backend for Cross-Origin Requests

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.

9. Testing and Running the Application

Verifying Functionality End-to-End

Follow these steps to test your Angular client with the Fiber backend:

  • Start the Fiber Backend: Ensure your Go Fiber server is running and listening on the specified port (e.g., 3000).
  • Run the Angular Application:
    ng serve
    Navigate to http://localhost:4200 in your browser.
  • Perform Login: Use the login form to authenticate. Upon successful login, you should be redirected to the dashboard displaying protected data.
  • Access Protected Routes: Attempt to navigate to protected routes without logging in to verify that the Auth Guard redirects you to the login page.
  • Logout Functionality: Implement and test the logout process to ensure that the session is properly terminated and access to protected routes is revoked.

10. Security Best Practices

Enhancing Application Security

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.

11. Conclusion

Bridging Angular with Fiber for Robust Authentication

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.

References


Last updated February 5, 2025
Ask Ithy AI
Export Article
Delete Article