typescript 将图像 src 的授权标头传递到 Ionic 页面中的远程服务器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47811784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:07:13  来源:igfitidea点击:

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

angularcordovatypescriptionic-framework

提问by Raghav

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

我有一个 Ionic 应用程序,它从远程服务器获取数据并将其显示在 Ionic html 页面上。

The remote URL is like this:

远程 URL 是这样的:

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

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.

这将为我提供一个“内容”的 JSON 对象,并将在 Ionic 应用程序的 html 页面中进一步使用。

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

它在 Ionic 应用程序内的 html 页面上是这样使用的:

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

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

“myObject”是从服务器收到的响应的 JSON 对象。

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.

“正文”字段包含要在段落中显示的 HTML。此“HTML”字段仅与整个“内容”对象一起从服务器返回。

"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.

您可以从上面的示例中看到图像在该 html 中。

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

将 html 从该字段渲染到 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.

我的应用程序被访客用户锁定,因此对于每个请求,我需要发送一个 Authorization 标头以对其进行身份验证,在这种情况下,所有图像都无法呈现,因为每个图像请求都将被视为服务器的访客。

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.

你能建议一个公共的地方,我的所有图像和其他来源,比如 html 应该通过,并且可以将授权标头连同它一起发送到服务器。

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.

我的目标是当它在 Ionic 应用程序中呈现时,将授权标头发送到该 Body 字段中存在的每个外部源(此处为图像)。

回答by Milan Hlinák

1) Create interceptor which sets authorization header

1)创建设置授权头的拦截器

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.

而不是<your token>您应该将您的 AuthService 注入这个拦截器,例如 this.authService.getToken(),它从本地存储加载令牌。

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

2) 实现“安全”管道,将图像作为 blob 并创建可在 src 属性中使用的 blob 的对象 url

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

3)使用它

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

回答by Hasan

1st Option: Look for "URL signing"

第一个选项:查找“URL 签名”

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.

这个想法是,当您使用时<img src="http://foo.com/image/1">,无法传递授权标头。因此,相反,您向后端发出发布请求,要求提供图像的临时公共链接,并将此链接作为图像来源。

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.

  1. 我需要显示“ http://foo.com/image/1

  2. 从浏览器向后端发出 post 请求,让他们知道您是授权客户端(包括授权标头),并要求提供一个将公开显示图像的临时 url

  3. 从后端,生成一个在有限时间内有效且不需要授权标头来显示图像的签名 url。

  4. 使用您刚刚收到的临时签名 url 作为 img 标签的 src。

2nd Option: Download the image and use blob URL

第二个选项:下载图像并使用 blob URL

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

这个问题的答案会告诉你:Force HTTP Interceptor in dynamic ngSrc request

回答by Deepak Jha

Here is how you write an interceptor,

这是你编写拦截器的方法,

  1. Need to extend a class called HttpInterceptor provided in angular 4/5.
  2. Override a method called intercept,
  1. 需要扩展 Angular 4/5 中提供的名为 HttpInterceptor 的类。
  2. 重写一个叫做intercept的方法,

It will add the header in all your http request, this would ideally be the place where you would perhaps need to put sanitation logic, for an example if you wish to put just certain request with that header you can decide that in intercept method.

它将在您的所有 http 请求中添加标头,理想情况下,这将是您可能需要放置卫生逻辑的地方,例如,如果您希望仅使用该标头放置某个请求,您可以在拦截方法中决定。

export class YourInterceptor implements HttpInterceptor{    
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
const NewRequest= req.clone({ headers: req.headers.set(‘Auth-Token', ‘YourAuthToken') });

return next.handle(NewRequest); }

返回 next.handle(NewRequest); }

After this you need to register this in your app.module.ts file in the manner given below,

在此之后,您需要以下面给出的方式在您的 app.module.ts 文件中注册它,

import { YourInterceptor } from './Your-interceptor';

now go to the @NgModule section and do this in your provider array, it would be to the provider array as given below,

现在转到@NgModule 部分并在您的提供程序数组中执行此操作,它将是如下所示的提供程序数组,

providers: [{provide: HTTP_INTERCEPTORS,useClass: YourInterceptor,multi: true}],

Now restart your app and whatever http call you make it will have a control inside which will intercept your code and you will be able to sail through.

现在重新启动你的应用程序,无论你调用什么 http ,它都会有一个控件,它会拦截你的代码,你就可以通过了。