我的拦截器在 Angular 版本 18 中不起作用。后端表示无法将标头添加到请求中:
Pre-authenticated entry point called. Rejecting access
2024-09-29T12:39:52.861+02:00 DEBUG 14733 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : Securing GET /error
2024-09-29T12:39:52.861+02:00 DEBUG 14733 --- [nio-8080-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-09-29T12:39:52.861+02:00 DEBUG 14733 --- [nio-8080-exec-4] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2024-09-29T12:39:53.031+02:00 DEBUG 14733 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing GET /posts/all
2024-09-29T12:39:53.046+02:00 WARN 14733 --- [nio-8080-exec-5] c.antonsteve96.ngrx.security.JwtFilter : Authorization header missing or does not start with 'Bearer '
2024-09-29T12:39:53.046+02:00 DEBUG 14733 --- [nio-8080-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2024-09-29T12:39:53.046+02:00 DEBUG 14733 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Secured GET /posts/all
2024-09-29T12:39:53.047+02:00 DEBUG 14733 --- [nio-8080-exec-5] horizationManagerBeforeMethodInterceptor : Authorizing method invocation ReflectiveMethodInvocation: public org.springframework.http.ResponseEntity com.antonsteve96.ngrx.post.PostController.getAllPosts(); target is of class [com.antonsteve96.ngrx.post.PostController]
2024-09-29T12:39:53.047+02:00 DEBUG 14733 --- [nio-8080-exec-5] horizationManagerBeforeMethodInterceptor : Failed to authorize ReflectiveMethodInvocation: public org.springframework.http.ResponseEntity com.antonsteve96.ngrx.post.PostController.getAllPosts(); target is of class [com.antonsteve96.ngrx.post.PostController] with authorization manager org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager@632fe645 and decision ExpressionAuthorizationDecision [granted=false, expressionAttribute=isAuthenticated()]
2024-09-29T12:39:53.047+02:00 DEBUG 14733 --- [nio-8080-exec-5] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2024-09-29T12:39:53.048+02:00 DEBUG 14733 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing GET /error
我希望作为前端的 Angular 可以将标头添加到请求中,并且不会使 http 调用失败。我正在尝试使用 JWT 令牌实现一项功能,该功能允许用户仅在登录时才能到达特定端点。为此,我需要拦截器正常工作:
import {ApplicationConfig, importProvidersFrom, isDevMode, provideZoneChangeDetection} from "@angular/core";
import {provideRouter} from "@angular/router";
import {routes} from "./app.routes";
import {provideClientHydration} from "@angular/platform-browser";
import {HTTP_INTERCEPTORS, provideHttpClient, withFetch} from "@angular/common/http";
import {StoreModule} from "@ngrx/store";
import {EffectsModule} from "@ngrx/effects";
import {AuthEffects} from "./auth/state/auth.effects";
import {provideStoreDevtools} from "@ngrx/store-devtools";
import {AuthService} from './services/auth.service';
import {counterReducer} from "./counter/state/counter.reducer";
import {COUNTER_STATE} from "./counter/state/counter.state";
import {POSTS_STATE} from "./posts/state/posts.state";
import {postsReducer} from "./posts/state/posts.reducer";
import {rootReducer} from "./store/root.state";
import {AuthInterceptor} from "./services/auth.interceptor";
import {PostsEffects} from "./posts/state/posts.effects";
import {PostsService} from "./services/posts.service";
export const appConfig: ApplicationConfig = {
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
PostsService,
AuthService,
provideZoneChangeDetection({eventCoalescing: true}),
provideRouter(routes),
provideClientHydration(),
provideHttpClient(withFetch()),
provideStoreDevtools({maxAge: 25, logOnly: !isDevMode()}),
importProvidersFrom(
StoreModule.forRoot(rootReducer),
EffectsModule.forRoot([AuthEffects]),
EffectsModule.forFeature([PostsEffects]),
StoreModule.forFeature(COUNTER_STATE, counterReducer),
StoreModule.forFeature(POSTS_STATE, postsReducer)
),
],
};
这是我的拦截器:
import { inject, Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import {Observable} from 'rxjs';
import {AuthService} from "./auth.service";
@Injectable({providedIn: "root"})
export class AuthInterceptor implements HttpInterceptor {
private authService = inject(AuthService); // Usa Store per selezionare il token
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(this.addAuthToken(request));
}
addAuthToken(request: HttpRequest<any>) {
const token = this.authService.getTokenFromLocalStorage();
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
})
}
}
您已经编写了一个基于类的拦截器,它是通过 DI 提供的。在这种情况下,您需要在提供 HTTP 客户端时显式启用基于 DI 的拦截器,使用
withInterceptorsFromDi()
函数:
{
providers: [
// ...
provideHttpClient(withFetch(), withInterceptorsFromDi())),
],
}
您缺少文档中的 withInterceptorsFromDi: 包括使用当前注入器中的多提供程序配置的基于类的拦截器到已配置的 HttpClient 实例中。