简体   繁体   English

Angular 5将令牌添加到标头中,然后使用httpClient发布

[英]Angular 5 Add Token to header before posting with httpClient

I am using a restapi and it requires that I add a token to the header before I can create a new record. 我正在使用restapi,它要求我在创建新记录之前向标头添加令牌。

Right now I have a service to create a new record which looks like this: 现在,我有一项服务可以创建一个新记录,如下所示:

service.ts 服务

create(title, text) {
    let headers: HttpHeaders = new HttpHeaders();
    headers = headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    headers = headers.append('Authorization', token); // Not added yet as this is the reason for the question
    return this.http.post('http://myapi/api.php/posts', {
      title: 'added title',
      text: 'added text'
    }, { headers });
  }

app.component.ts app.component.ts

add() {
    this.service.create('my title', 'body text').subscribe(result => {
      console.log(result);
    });
  }

The problem with this is that it won't let me add the new record because it requires a token and in order to get a token I need to run this: 问题是它不允许我添加新记录,因为它需要一个令牌,为了获得令牌,我需要运行以下命令:

getToken() {
    let headers: HttpHeaders = new HttpHeaders();
    headers = headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    return this.http.post('http://myapi/api.php/user', {
      username: 'admin',
      password: 'password'
    }, { headers });
  }

My question is...How do I get this two together into one call instead of two...or when is the best way to do this? 我的问题是...如何将这两个在一起打成一个电话而不是两个...或者什么时候是最佳方法?

Apart from what @Pardeep Jain already mentioned, you can add an interceptor (> Angular version 4, you mentioned you're using 5) for your HttpClient that will automatically add Authorization headers for all requests. 除了已经提到的@Pardeep Jain之外,您还可以为HttpClient添加拦截器(> Angular版本4,您提到使用的是5),该拦截器将自动为所有请求添加Authorization标头。

If you need top be authenticated for only one request, it's better to keep things simple and use Pardeep's solution. 如果您只需要为一个请求对top进行身份验证,则最好使事情简单并使用Pardeep的解决方案。

If you want to be authenticated for most of your requests, then add an interceptor. 如果您想对大多数请求进行身份验证,请添加一个拦截器。

module, let's say app.module.ts 模块,比如说app.module.ts

@NgModule({
 //...
 providers: [
    //...
    {
      provide: HTTP_INTERCEPTORS,
      useClass: JwtInterceptor,
      multi: true
    },
    //...
    ]
//...
})

and your jwt interceptor, let's say jwt.interceptor.ts 和你的jwt拦截器,比如说jwt.interceptor.ts

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
  constructor(private injector: Injector, private router: Router) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {  
    const authReq = req.clone({
      headers: req.headers.set('Authorization', /* here you fetch your jwt */this.getToken())
        .append('Access-Control-Allow-Origin', '*')
    }); 
    return next.handle(authReq).do((event: HttpEvent<any>) => {
      if (event instanceof HttpResponse) {
        // do stuff with response if you want
      }
    }, (response: HttpErrorResponse) => { });
  }

  getToken() {
    let headers: HttpHeaders = new HttpHeaders();
    headers = headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    return this.http.post('http://myapi/api.php/user', {
      username: 'admin',
      password: 'password'
    }, { headers });
  }
}

If you want to read something, more here: https://medium.com/@ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8 如果您想阅读某些内容,请访问: https//medium.com/@ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8

The code should be like this - 代码应该是这样的-

create(title, text) {
    let headers: HttpHeaders = new HttpHeaders();
    headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    headers.append('Authorization', token);
    return this.http.post('http://myapi/api.php/posts', {
      title: 'added title',
      text: 'added text'
    }, { headers });
  }

My question is...How do I get this two together into one call instead of two...or when is the best way to do this? 我的问题是...如何将这两个在一起打成一个电话而不是两个...或者什么时候是最佳方法?

You should not. 你不应该。
Authentication is one thing that should be performed a single time for the client or as the authentication ticket has expired. 身份验证是客户端应该执行的一件事,或者身份验证票证已过期。
Posting some content is another thing that you should not mix with authentication. 发布一些内容是您不应与身份验证混在一起的另一件事。

So authenticate the client once and store the ticket. 因此,对客户端进行一次身份验证并存储票证。
Then pass the ticket in the header for any request to a secured endpoints/methods. 然后,将针对任何请求的标头中的票证传递给安全的端点/方法。 Or use a transverse way as an interceptor to set it in the send requests if you don't want to repeat the code. 如果不想重复代码,也可以使用横向方式作为拦截器在发送请求中进行设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM