简体   繁体   中英

cannot read a response header in angular

I am trying to implement a token based authentication with spring boot and angular. The authentication token is exposed to HTTP response headers with a same name token. In angular I have a following request to my api in my service file:

login(username: string, password: string): Observable<any> {

    return this.http.post(AUTH_API + 'login', {
      username,
      password

    }, httpOptions);
  }

And a following component ts method:

onSubmit(): void {
    const { username, password } = this.form;
     this.authService.login(username, password).subscribe({
      next: data => {
       console.log(data.headers.get('token'));
        //this.tokenStorage.saveToken(data.accessToken);

        this.tokenStorage.saveUser(data);

        this.isLoginFailed = false;
        this.isLoggedIn = true;
        this.roles = this.tokenStorage.getUser().roles;

        this.reloadPage();
      },


      error: err => {
     //  console.log( this.tokenStorage.getUser().roles);
       console.log("ERR");
        this.errorMessage = err.error.message;
        this.isLoginFailed = true;
      }
    });

  }

When I try to show the token header in console I am getting the following error: TypeError: Cannot read properties of null (reading 'headers') Here is my cors configuration from spring boot in security config class:

 CorsConfigurationSource corsConfigurationSource() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
           
            source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
           // source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
            CorsConfiguration conf=   new CorsConfiguration().applyPermitDefaultValues();
            conf.setExposedHeaders(Arrays.asList("token"));
             source.registerCorsConfiguration("/**", conf);
                
            return source;
        

The token header is visible in a postman or a chrome consol, but not in angular front end. What am I missing? Http options

protected void configure(HttpSecurity http) throws Exception {
            http.cors().and().csrf().disable().authorizeRequests()
                    .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .addFilter(new AuthenticationFilter(authenticationManager()))
                    .addFilter(new AuthorizationFilter(authenticationManager()))
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }

Angular http options

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

Headers

Request URL: http://localhost:8080/login
Request Method: POST
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: token
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Sat, 29 Jan 2022 22:06:39 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
token: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0MTAiLCJleHAiOjE2NDM1MDU5OTl9.xtZxAU-TbpUmWFm_CuKS7iCHu-FiBs332cCVlxca6AwY4XOz-K7GJ4yB8PLLjk1JuXcgs1sbcVHeBto7iW7rpA
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Content-Length: 41
Content-Type: application/json
Host: localhost:8080
Origin: http://localhost:8081
Referer: http://localhost:8081/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36

You have to set the part that needs to be observed within the options:

const httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
    observe: 'response'
};
return this.http.post(AUTH_API + 'login', {
    username,
    password
}, httpOptions);

That will give you the whole response so that your data parameter within the subscription callback will contain headers and body .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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