Hone logo
Hone
Problems

Implementing an Authentication Interceptor in Angular

Authentication interceptors are crucial for securing Angular applications by automatically adding authentication tokens (like JWTs) to outgoing HTTP requests. This challenge asks you to implement an Angular HTTP interceptor that intercepts requests, adds an authorization header if a token exists, and handles unauthorized responses (e.g., 401) by redirecting the user to the login page. This is a common pattern for protecting API endpoints and ensuring only authenticated users can access sensitive data.

Problem Description

You need to create an Angular HTTP interceptor that performs the following actions:

  1. Intercepts Outgoing Requests: The interceptor should intercept all outgoing HTTP requests made by your Angular application.
  2. Adds Authorization Header: If a valid JWT (JSON Web Token) is stored in local storage under the key 'authToken', the interceptor should add an Authorization header to the request with the value Bearer <token>.
  3. Handles Unauthorized Responses: If the server responds with a 401 (Unauthorized) or 403 (Forbidden) status code, the interceptor should:
    • Remove the token from local storage.
    • Redirect the user to a predefined login route (e.g., /login).
  4. Preserves Original Request: The interceptor should ensure that the original request is ultimately sent to the server, with the added authorization header (if applicable).

Key Requirements:

  • The interceptor must be injectable as an Angular service.
  • The interceptor must correctly handle cases where a token is present, absent, or invalid.
  • The redirection to the login route should be handled gracefully without causing errors.
  • The interceptor should not interfere with requests that do not require authentication (e.g., public API endpoints).

Expected Behavior:

  • When a request is made with a valid token in local storage, the Authorization header is added.
  • When a request is made without a token, the header is not added.
  • Upon receiving a 401 or 403 response, the token is removed, and the user is redirected to the login page.
  • The application continues to function correctly after the redirection.

Edge Cases to Consider:

  • Token expiration: While this challenge doesn't require token refresh, consider how your interceptor might be extended to handle expired tokens in the future.
  • Race conditions: Ensure that token removal and redirection are handled correctly to avoid unexpected behavior.
  • Requests to non-API endpoints: The interceptor should not interfere with requests to routes within your Angular application.

Examples

Example 1:

Input: A request to '/api/protected-resource' with a valid JWT stored in local storage as 'authToken'.
Output: The request is sent to '/api/protected-resource' with an 'Authorization' header: 'Bearer <token>'.
Explanation: The interceptor detects the token, adds the header, and allows the request to proceed.

Example 2:

Input: A request to '/api/public-resource' with no token in local storage.
Output: The request is sent to '/api/public-resource' without an 'Authorization' header.
Explanation: The interceptor does not add the header because no token is present.

Example 3:

Input: A request to '/api/protected-resource' with a valid JWT. The server responds with a 401 Unauthorized status code.
Output: The token is removed from local storage, and the user is redirected to '/login'.
Explanation: The interceptor detects the 401 status, removes the token, and redirects the user.

Constraints

  • The Angular version should be Angular 14 or higher.
  • The token should be stored in local storage as a string.
  • The login route should be configurable (e.g., through a constant or service). Assume the login route is /login.
  • The interceptor should be efficient and not introduce significant performance overhead. Avoid unnecessary computations or DOM manipulations.
  • Error handling should be robust and prevent the application from crashing.

Notes

  • Consider using Angular's Router service for redirection.
  • The intercept() method of the HttpInterceptor interface is where the core logic resides.
  • Think about how to handle different types of HTTP requests (GET, POST, PUT, DELETE, etc.). The provided solution should work for all request types.
  • This challenge focuses on the core functionality of the interceptor. Additional features like token refresh or error logging can be added as extensions.
Loading editor...
typescript