Enhancing Image Security: Getting Authenticated Images with Impure Pipe in Angular

With this blog post, we’re extending our previous post on handling the authentication of images and other assets in Angular applications.

Nataliia Podpriatova
medialesson

--

Our main objective was to alleviate components from the responsibility of authenticating images while also establishing a unified solution. After some investigation, our initial consideration led us to the @this-dot/ng-utils solution. However, upon closer examination, we discovered that it didn’t fully align with our specific requirements. Here’s a more detailed breakdown:

  1. Dependency Concerns: Introducing another dependency, especially for just one pipe, raises concerns about potential issues it might introduce, particularly during Angular updates.
  2. Lack of SVG Support: Our project involves SVG icons, so it’s crucial for any utility solution to support them seamlessly.
  3. Object URL Cleanup: The solution lacks object URL cleanup functionality, which is crucial for preventing memory leaks and ensuring efficient resource management, particularly since our application deals with a large volume of dynamically generated resources.

Building on the inspiration drawn from the @this-dot/ng-utils library, we’ve developed a custom solution: the impure pipe with HttpClient. This utility streamlines the process of fetching authorized images while offering enhanced security and efficiency. Let’s dive into how this pipe works and how it can benefit your Angular projects 🤓

Why HttpClient is inside the pipe?

The concept proposed by @this-dot/ng-utils, which involves fetching images using HttpClient, appeared to be a promising solution to us. Requests interact with all necessary HttpInterceptor implementations, ensuring that the “Authorization” header is automatically added to each request. In this custom image pipe, we leverage several essential services to handle HTTP requests, sanitize URLs, and ensure smooth change detection. These are their roles in our pipe implementation:

HttpClient — allows us to make HTTP requests to fetch image data from the provided image paths and adds necessary authorization headers;

DomSanitizer— is used to sanitize the image URLs obtained from the HTTP response. It helps prevent security vulnerabilities by ensuring that the URLs are safe to use in the application. It provides us with the capability to utilize the bypassSecurityTrustUrl, enabling the display of the returned blob safely;

ChangeDetectorRef — manually triggers change detection after updating the latest value of the pipe. This ensures that any changes are detected and reflected in the application’s view. Below is a code snippet featuring the constructor of a pipe, illustrating its setup and functionality.

The next section of the code ensures that if a previously existing object URL is already in place and it’s a blob URL, it gets revoked.

tap((imagePath: string | SafeUrl) => {
if (this.latestValue && typeof this.latestValue === 'string') {
URL.revokeObjectURL(this.latestValue);
}}

Stateful images with FontAwesome icons

Our next task was to address the handling of loading and error states. We aimed to incorporate the FontAwesome icon library to display SVG icons, enriching the user experience by providing visual cues for the loading process and error states of images.

The IconDefinition interface introduced by fontawesome icon library specifies the following structure of an icon:

export interface IconDefinition extends IconLookup {
icon: [
number, // width
number, // height
string[], // ligatures
string, // unicode
IconPathData // svgPathData
];
}

The main problem is to tweak the icon sizes to match the image size. It seems we’re in for a bit of array tinkering… 🪚

This action helps prevent potential memory leaks by cleaning up resources when the pipe is destroyed.

public ngOnDestroy(): void {
this.subscription.unsubscribe();
// Revoke the object URL if it is a blob URL
if (typeof this.latestValue === 'string') {
URL.revokeObjectURL(this.latestValue);
}
}

There’s still plenty of room for exploration with this pipe! 💫 We could make the icons dynamic or prepare the pipe to display either images and/or icons depending on the input, and so on. But my main idea was to uncover the essence of this approach.

It’s time to dive into the outcome! 🚀

This is an example of using the httpImgSrc pipe to safely fetch images.

<img [src]="pic.thumbnailUrl | httpImgSrc" 
alt="Your best attempt at generating a fancy alt text!" />

It works! 🪄

In conclusion, the implementation of the httpImgSrc pipe addresses the crucial need to integrate authorization headers into image requests. Leveraging the capabilities of the HttpClient, we successfully incorporate authorization headers, ensuring secure and authenticated access to image resources. By utilizing asynchronous operations and the FontAwesome icon library, we dynamically handle the display of loading and error SVG icons, enhancing the user experience. However, there is still ample room for further enhancements.

Hope this can help! Share your thoughts too!

--

--