angular - Välitetään valtuutusotsikko kuvien src:lle etäpalvelimelle Ionic-sivulla


Minulla on Ionic-sovellus, joka hakee tiedot etäpalvelimelta ja näyttää ne Ionic HTML -sivulla.

Etäosoite URL on tällainen:

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

Tämä antaa minulle JSON-objektin nimeltä "content" ja sitä käytetään edelleen Ionic-sovelluksen HTML-sivulla.

Sitä käytetään näin HTML-sivulla Ionic-sovelluksen sisällä:

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

"myObject" on JSON-objekti, joka saatiin palvelimelta vastauksena.

"Body"-kenttä sisältää HTML:n, joka näytetään kappaleessa. Tämä "HTML"-kenttä palautetaan palvelimelta vain yhdessä koko "content"-objektin kanssa.

"Body"-kentässä voi olla sisältöä kuten tämä:

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

Voit nähdä yllä olevasta esimerkistä, että kuvat ovat siellä kyseisessä HTML:ssä.

Minulla ei ole ongelmaa renderöidä HTML:ää siitä kentästä Ionic-sivulle.

Minulla on tässä yksi ongelma, että kuvani eivät näy siellä.

Tässä on syy..

Sovellukseni on lukittu vieraskäyttäjille, joten jokaista pyyntöä varten minun täytyy lähettää valtuutusotsikko todentaakseni sen, ja tässä tapauksessa kaikkia kuvia ei voida näyttää, koska jokainen kuvan pyyntö käsitellään palvelimella täällä vieraana.

Voitko ehdottaa yleistä paikkaa, jonka kautta kaikki kuvani ja muut lähteeni, kuten HTML:ssä, kulkisivat ja joka voisi lähettää valtuutusotsikon palvelimelle sen mukana.

Minulla on jo valtuutustunnus paikallisessa tallennuskohteessa.

Tavoitteeni on lähettää valtuutusotsikko jokaiselle ulkoiselle lähteelle (kuva tässä), joka on kyseisessä Body-kentässä, kun se renderöityy Ionic-sovelluksessa.

Vastaus #1

1) Luo sieppaaja, joka asettaa valtuutusotsikon

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

Sen sijaan, että käytät <your token>, sinun tulisi injektoida AuthService tähän interceptoriin, esimerkiksi this.authService.getToken(), joka lataa tokenin paikallisvarastosta.

2) Toteuta "turvallinen" putki, joka saa kuvan blobina ja luo tästä blobista objektin URL-osoitteen, jota voidaan käyttää src-attribuutissa

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) Käytä sitä

<img [attr.src]="'your link' | secure | async" />

Vastaus #2

1. Vaihtoehto: Etsi "URL:n allekirjoitus"

Ajatuksena on, että kun käytät <img src="http://foo.com/image/1">, ei ole tapaa välittää valtuutusotsikoita. Sen sijaan teet post-pyynnön omaan backendisi kysyäksesi väliaikaista julkista linkkiä kuvalle ja asetat tämän linkin kuvan lähteeksi.

Tässä on esimerkkivirtaus

  1. Minun täytyy näyttää "http://foo.com/image/1"

  2. Selaimesta tee POST-pyyntö backendille, kerro heille, että olet valtuutettu asiakas (sisällytä valtuutusotsikko), ja pyydä väliaikaista URL-osoitetta, joka näyttää kuvan julkisesti

  3. Luo backendistä allekirjoitettu URL-osoite, joka on voimassa vain rajoitetun ajan eikä vaadi valtuutusotsikoita kuvan näyttämiseen.

  4. Käytä juuri vastaanottamaasi tilapäistä allekirjoitettua URL-osoitetta img-tagin src-attribuuttina.

2. vaihtoehto: Lataa kuva ja käytä blob-URL:ia

Vastaukset tähän kysymykseen kertovat sinulle siitä: Pakota HTTP-interseptori dynaamisessa ngSrc-pyynnössä

Aiheeseen liittyviä artikkeleita