Topic 16: 5 steps for Authentication and Security

image 2

Play Store Application link – Java to Angular in 19 Steps – App on Google Play

Authentication in Java vs angular

In Java, particularly with Spring Security, JWT (JSON Web Token) authentication is widely used for securing REST APIs. The token is typically generated on the server-side and then sent to the client. Once the client receives the token, it can store it (usually in localStorage or sessionStorage) and send it with each subsequent request to access protected resources.

Java Example (Spring Security JWT Authentication):

In Java, authentication is often done by creating an endpoint that issues the JWT token when the user logs in.

@RestController
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtTokenProvider tokenProvider;
    @PostMapping("/login")
    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                loginRequest.getUsername(),
                loginRequest.getPassword()
            )
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = tokenProvider.generateToken(authentication);
        return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
    }
}

In this Spring Security example, the backend generates a JWT token upon successful login, which can then be sent by the client for future API calls.


Introduction to Authentication in Angular

In Angular, authentication is commonly handled via JWT, much like in Java Spring. The JWT is sent from the backend after a successful login, and Angular stores it in localStorage or sessionStorage. The token is then included in the Authorization header of all HTTP requests made to the server.

Angular also provides route guards to protect routes that require authentication and interceptors to handle token expiration and attach the token to every request automatically.


Tabular Comparison: Authentication in Java vs. Angular

FeatureJava (Spring Boot)Angular (Frontend)
JWT GenerationSpring Security JWT ProviderBackend API (Spring)
Storing TokenClient-side (localStorage/sessionStorage)Client-side (localStorage/sessionStorage)
Sending TokenHTTP requests with Authorization: Bearer <token>HTTP requests using HttpClient with interceptors
Route ProtectionSpring Security (@PreAuthorize)Angular Route Guards
Token Expiration HandlingManual token expiration check (backend)HTTP Interceptor for automatic token refresh
Interceptor SupportManual integration (via filters)HttpClient interceptors for token handling and errors

As shown, Java relies on Spring Security for managing JWT tokens, while Angular uses HttpClient with interceptors for token management and route protection.


JWT Authentication Flow in Angular

Here’s how the JWT authentication flow works in Angular:

  1. The client sends the username and password to the backend API.
  2. The backend verifies the credentials and returns a JWT token.
  3. Angular stores the token in localStorage or sessionStorage.
  4. For subsequent requests, Angular attaches the token in the Authorization header.
  5. If the token expires, Angular handles the error and can refresh the token using an interceptor.

This mirrors Java’s approach, where the token is stored and used for subsequent requests. Both platforms can handle token expiration and security issues similarly but use different tools in their respective environments.


Complete Code Example: Angular JWT Authentication with HttpClient and Interceptors

Step 1: Set Up Authentication Service (Angular)

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private apiUrl = 'https://your-backend-api.com/login';
  constructor(private http: HttpClient) {}
  login(username: string, password: string): Observable<any> {
    return this.http.post(this.apiUrl, { username, password }).pipe(
      catchError(this.handleError)
    );
  }
  private handleError(error: any): Observable<never> {
    // Handle error (e.g., token expired, invalid credentials)
    throw error;
  }
}

In this AuthService, the login method sends the login credentials to the backend and expects a JWT token in response.

Step 2: Create an HTTP Interceptor for JWT Handling

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = localStorage.getItem('jwtToken');
    
    if (token) {
      const clonedRequest = req.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
      return next.handle(clonedRequest);
    }
    
    return next.handle(req);
  }
}

Here, the AuthInterceptor adds the JWT token to the Authorization header of each outgoing HTTP request.

Step 3: Protect Routes with Route Guards

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private router: Router) {}
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const token = localStorage.getItem('jwtToken');
    
    if (token) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }
}

AuthGuard checks if a token is present in localStorage. If the token exists, the route is activated; otherwise, the user is redirected to the login page.


Java Comparison: Token Expiration and Security

In Java, token expiration handling and route protection are typically done in Spring Security:

  1. Token Expiration: Spring can check the expiration time of the JWT and refresh it if necessary.
  2. Route Protection: @PreAuthorize or custom filters in Spring Security are used to protect routes from unauthorized access.

Java Example (Spring Security):

@PreAuthorize("hasRole('USER')")
@GetMapping("/profile")
public ResponseEntity<?> getUserProfile() {
    // This route is protected and requires a valid token
    return ResponseEntity.ok("User Profile");
}

In this example, Spring Security uses @PreAuthorize to protect routes. Similarly, Angular uses Route Guards to prevent access to certain pages without proper authentication.


Major Version Differences in Angular for Authentication

  • Angular 5: Required manual configuration for interceptors, and JWT token handling was more manual.
  • Angular 6+: HttpClient interceptors streamlined JWT authentication, making token handling and route protection much easier and more integrated.

Conclusion

In both Java and Angular, JWT authentication is essential for securing web applications. Java Spring Security handles JWT generation and validation on the backend, while Angular handles token storage, automatic token attachment to HTTP requests, and route protection via guards and interceptors. These concepts are similar across both technologies, allowing Java developers to easily transition to Angular when building secure web applications.

By leveraging HttpClient and interceptors, Angular offers an efficient way to manage JWT authentication, similar to how Spring Security works in the backend. This ensures seamless integration between frontend and backend, keeping your application secure.


This blog post explains JWT authentication in Angular, with a direct comparison to Java Spring, helping Java developers easily understand how security and authentication work in both ecosystems.

Leave a Reply

Your email address will not be published. Required fields are marked *