Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing authorization header for images src to remote server in Ionic page

I have an Ionic app where it fetches the data from remote server and displays it on Ionic html page.

The remote URL is like this:

http://foo.com/api/content/1

This will give me a JSON object of "content" and will be used further in the html page of Ionic app.

It is being used like this on html page inside Ionic app:

<div class="article-desc">
  <p [innerHtml]="myObject?.Body"></p>
</div>

"myObject" is the JSON object of response received from the server.

The "Body" field contains the HTML to be displayed in the paragraph. This "HTML" field is being returned from server only along with the entire "content" object.

"Body" field can have content like this:

<p>blah blah <img src="http://foo.com/image/1"/> blah blah <img src="http://foo.com/image/2"/>blah blah blah </p>

You can see from the above example that the images are there in that html.

I have no issue rendering the html from that field to Ionic Page.

I have one issue here that my images are not being rendered there.

Here is why..

My app is locked for Guest users so for each request I need to send an Authorization header in order to authenticate it and in this case all the images are not able to render because each image request will be treated as guest here for server.

Can you suggest a common place where all my images and other sources like there in html should pass through and can send authorization header along with it to server.

I already have the Authorization Token in local storage item.

My goal is to send authorization header to each external source (image here) present in that Body field when it renders in Ionic app.

like image 515
Raghav Avatar asked Dec 14 '17 11:12

Raghav


2 Answers

1) Create interceptor which sets authorization header

import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        request = request.clone({
            setHeaders: {
                Authorization: `Bearer <your token>`
            }
        });

        return next.handle(request);
    }
}

Instead of <your token> you should inject your AuthService into this interceptor, for example this.authService.getToken(), which loads token from local storage.

2) Implement "secure" pipe which gets image as blob and creates an object url of that blob that can be used in the src attribute

import { Pipe, PipeTransform } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { Observable } from 'rxjs/Observable';

@Pipe({
    name: 'secure'
})
export class SecurePipe implements PipeTransform {

    constructor(private http: HttpClient, private sanitizer: DomSanitizer) { }

    transform(url): Observable<SafeUrl> {
        return this.http
            .get(url, { responseType: 'blob' })
            .map(val => this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val)));
    }

}

3) Use it

<img [attr.src]="'your link' | secure | async" />
like image 119
Milan Hlinák Avatar answered Nov 02 '22 12:11

Milan Hlinák


1st Option: Look for "URL signing"

The idea is that, when you use <img src="http://foo.com/image/1"> there is no way to pass the authorization headers. So instead, you make post request to your backend to ask for a temporary public link for the image and put this link as source of image.

Here is an example flow

  1. I need to show "http://foo.com/image/1"

  2. From the browser, make a post request to backend, let them know you are an authorized client (include the authorization header), and ask for a temporary url that will show the image publicly

  3. From the backend, generate a signed url that is valid for a limited time and does not require authorization headers to show the image.

  4. Use the temporary signed url you just received as src of the img tag.

2nd Option: Download the image and use blob URL

Answers to this question will tell you about it: Force HTTP interceptor in dynamic ngSrc request

like image 28
Hasan Avatar answered Nov 02 '22 12:11

Hasan