来自 Angular 18 的带有不记名令牌的正确请求在 spring 中得到空标头

问题描述 投票:0回答:1

我的角度项目正在运行。在步骤 1 中,我可以登录并从我的 Spring Boot 应用程序获取令牌。我将此令牌保存到本地存储。该请求是可能的,因为没有被身份验证阻止。

问题是当我想使用不记名令牌发出请求时。我的 Angular 应用程序发送了一个带有正确标头的请求,但我的 Spring 应用程序无法检测到它。最令人惊讶的是,如果我用 Postman 调用相同的请求,它工作得很好。

首先,我正在使用这些版本:

  • 角度:18.2.8
  • rxjs 7.8.1
  • 打字稿5.5.4
  • zone.js 0.14.10
  • 春季启动3.3.4

来自 Angular 的调用示例之一是这个(测试函数):

组件.ts

test() {
    this.userService.getUserByUsername('user').subscribe({
      next: (data:any) => {
        console.log(data);
      },
      error: (err) => console.log('Fail', err)
    })
  }

用户.Service.ts

@Injectable({
  providedIn: 'root'
})
export class UserService {

  url: string;
  constructor(private http:HttpClient) { 
    this.url = environment.domainUrl + '/users';
  }

  public getUserByUsername(username:string): Observable<any> {
    return this.http.get(`${this.url}/username/${username}`).pipe(
      tap((response:any) => {
        if(response.user){
          console.log(response.user)
        }
      })
    );
  }

}

auth.interceptor.ts

import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from './auth.service';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
    console.log("Intercepting Requests");
    const authService = inject(AuthService);
    const token = authService.getToken();
    let authReq = req;

    if (token) {
        authReq = req.clone({
            setHeaders: {
                Authorization:'Bearer ' + token
            }
        });
        console.log("Token added to request:", token);
        console.log(authReq);
    } else {
        console.log("No token found");
    }

    return next(authReq);
};

app.config.ts

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './services/auth/auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }), 
    provideRouter(routes), 
    provideAnimationsAsync(), 
    provideHttpClient(withInterceptors([authInterceptor]))
  ]
};

现在,我们可以看到浏览器控制台了。其中一项要求: Request

如果我们搜索请求头,我们可以看到: full request

但是,在 Spring boot 应用程序中,我得到的 authHeader 为 null。

片段 getToken

private String getTokenFromRequest(HttpServletRequest request) {
        final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);

        if(StringUtils.hasText(authHeader) && authHeader.startsWith("Bearer "))
        {
            return authHeader.substring(7);
        }
        return null;
    }

我必须澄清,如果我在 Postman 中使用相同的令牌,我会得到正确的响应。

我对这个问题感到非常困惑,我不知道发生了什么。感谢您的帮助。

angular spring spring-boot bearer-token angular18
1个回答
0
投票

解决方案如下:

在 Spring boot 应用程序中,我刚刚在 securityfilterchain 中添加了 cors 禁用选项和 OPTIONS 匹配器权限。

现在SecurityCOnfig的securityFilterChain是这样的:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authRequest ->
                        authRequest
                                .requestMatchers(HttpMethod.OPTIONS).permitAll()
                                ...
                .cors(AbstractHttpConfigurer::disable);

        return http.build();
    }

感谢大家的帮助,特别是Daniel Sprohar

© www.soinside.com 2019 - 2024. All rights reserved.