spring-security 在Angular中使用HTTP INTERCEPTOR时未获得JSON响应

zte4gxcn  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(131)

我在我的项目中使用JWT身份验证,它运行良好。
我面临的问题是,在使用HTTP INTERCEPTOR之前,我能够从后端(Sping Boot REST API)获得正常的JSON响应。
但是,在使用HTTP INTERCEPTOR**(用于在所有HTTP请求中添加AUTHENTICATION头)之后,我没有得到JSON响应,而是得到了[Object object]**形式的响应。

最重要的是,后端以JSON格式给出响应,我使用 Postman 检查了它。
身份验证拦截器.ts文件

intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    //get token from auth service
    let token: any = this.authService.getToken();

    //check if guest user is a first time visitor
    if (!token) {
      alert('no token present');
      return next.handle(request.clone());
    }

    //add token and header to the request
    request = this.addTokenAndHeader(request, token);

    //return
    return next.handle(request).pipe(
      catchError((err: HttpErrorResponse) => {
        alert('inside catch and pipe');
        //redirect to login page if error code 401 or 403
        if (err.status === 401 || err.status === 403) {
          alert(err.status);
          this.authService.clear();
          this.router.navigateByUrl('/access/login');
        }
        return throwError('Something went wrong.');
      })
    );
  }

  //add token to http request
  private addTokenAndHeader(request: HttpRequest<any>, token: string) {
    alert('inside add token and header method');
    return request.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`,
      },
    });
  }

加载程序.拦截程序.ts

intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    this.loaderService.isLoading.next(true);
    return next.handle(request).pipe(
      finalize(() => {
        this.loaderService.isLoading.next(false);
      })
    );
  }

应用程序.模块.ts文件

@NgModule({
  declarations: [AppComponent, NoInternetComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    MaterialModule,
    BrowserAnimationsModule,
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: LoaderInterceptor,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

user.service.ts-我在这里调用API URL。在这里我可以得到正常的JSON响应。但是,使用HTTP INTERCEPTOR后没有得到。最重要的是,后端是以JSON格式给出响应的,我用 Postman 检查了一下。

getUserByPhone(phone: any) {
    return new Promise((resolve) => {
      this.http
        .get(this.constants.apiURL + '/user/get/phone/' + phone)
        .subscribe((data: any) => {
          alert('inside getuserbyphone method');
          alert(data);
          resolve(data);
        });
    });
  }

您的帮助将是非常感谢的。请站出来帮助我在这种情况下,如果你有任何信息reagrending相同。提前感谢解决我的问题。真的很感激。

pgpifvop

pgpifvop1#

有两种方法可以处理这个问题,和您已经尝试过的方法之一,例如使用'JSON. stringify'。虽然这可能不是一个坏的选择,但考虑到拦截器将保留在原地。但如果您不能/不'我不想更新已经写好的应用程序代码,而只是想通过拦截器来实现这一点,那么在这种情况下,我认为您需要更新拦截器代码,以便在在应用程序中使用它。
你应该创建一个单独的拦截器(最好的做法,如果你想在同一个拦截器中这样做,这是完全可选的)来格式化响应。由于你没有共享它,你介意检查一下响应中[Object对象]的类型吗?我认为它应该是HTTPResponse类型。
默认情况下,您应该在返回数据的'body'键中看到响应数据。我创建了一个快速示例,下面是拦截器的代码片段。

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http";
    import { Injectable } from "@angular/core";
    import { Observable } from "rxjs";
    import { filter, map } from "rxjs/operators";

    @Injectable({
      providedIn: 'root',
    })
    export class FormatResponseInterceptor implements HttpInterceptor {

      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
          return next.handle(request).pipe(
            filter(event => event instanceof HttpResponse),
            map((event: HttpResponse<any>) => event.clone({ body: event.body }))
          );
        }
    }

这样你就可以在你的应用程序中直接使用它,如下所示:

import { SampleService } from './service/sample.service';

export interface CatInterface {
  fact: string | '',
  length: number | 0;
}
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  name = 'Angular ' + VERSION.major;
  apiData: CatInterface;

  constructor(private sampleService: SampleService){}

  ngOnInit(){
   this.invokeAPI(); 
  }

  private invokeAPI(){

       this.sampleService.readData().subscribe({
         next: (res)=>{
           this.apiData = {...res};
         },
         error: (err)=>{},
         complete:()=>{console.log('Service Subscription Completed!');
        }
       })
  }
}

在上面的代码中,我只是解构了响应对象。
因此,您首先需要检查响应对象结构,并相应地使用它。
下面是我的app.component.html代码,以了解更多信息:

<hello name="{{ name }}"></hello>

<p><span style="background-color: yellow"> FACT from the API is : </span> <b> {{apiData?.fact}}</b></p>
<p> <span style="background-color: yellow">LENGTH from the API is : </span><b> {{apiData?.length}}</b></p>

下面是输出的屏幕截图:

希望这将帮助您解决您的问题。请让我知道提供您的反馈意见,以便它将帮助其他人以及在未来。

相关问题