【问题标题】:CORS problem when sending Bearer token from angular [closed]从角度发送承载令牌时出现CORS问题[关闭]
【发布时间】:2020-11-29 05:32:06
【问题描述】:

问题是向本地主机发送 GET 请求时未发送授权标头。 预检请求 ( OPTIONS ) 不包含授权标头并返回 401 状态。 我正在使用 Angular 拦截器将标头添加到我的请求中,并将 Spring Boot 作为后端服务器。 这是发送 GET 请求时开发人员 Firefox 中的控制台。 enter image description here

【问题讨论】:

  • 您是否在服务器上设置了 CORS?
  • 您还需要在后端服务中启用 cors origin。我猜你在构建 api 时错过了那部分。请参阅以下文档以遵循有关如何为某些特定端点启用 cors 来源的说明。 spring.io/guides/gs/rest-service-cors
  • 在我的休息控制器上,我添加了@CrossOrigin("*") 并在后端过滤器中添加了响应头。所以我确实处理得很好。顺便说一句,感谢您这么快回答。
  • 您是否使用 auth0 来获取令牌?您还可以在网络部分的检查中查看您的请求。并且可以验证您缺少什么。
  • 是的,我做到了。我在启用所有来源的控制器上添加了注释,并且在标题中我添加了 Access-Control-Allow-Origin 作为响应。

标签: angular spring-boot cors authorization angular9


【解决方案1】:

您的 CORS 过滤器:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;
import java.util.List;    

@Component
public class CorsFilterConfig {

    public static final List<String> allowedOrigins = Arrays.asList("*");

    @Bean
    public FilterRegistrationBean<CorsFilter> initCorsFilter() {
        // @formatter:off
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
        config.addAllowedMethod("*");
        config.setAllowedOrigins(allowedOrigins);
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
        // @formatter:on
    }
}

Angular 的拦截器:

    import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,

  HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { AppService } from '../services/app.service';
import { Router } from '@angular/router';
import { environment } from 'src/environments/environment';
import { tap } from 'rxjs/operators';
import { ProgressBarService } from '../services/progress-bar.service';

@Injectable()
export class HttpTokenInterceptor implements HttpInterceptor {
  constructor(private app: AppService, private router: Router,
              private progressService: ProgressBarService) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const url = environment.api_url;
    if (req.url.indexOf('/oauth/') === -1) {  
      const token = this.app.getToken();
      const contentType = req.url.indexOf('/fileupload') >= 0  ? 'multipart/form-data' : 'application/json; charset=utf-8';
      let changeReg = req.clone({
        url: url + req.url,
        headers: req.headers
          .set('Content-Type', 'application/json; charset=utf-8')
          .set('Accept', 'application/json; charset=utf-8')
          .set('Authorization', token)
      });
      if (req.url.indexOf('/upload') >= 0 || req.url.indexOf('/fileupload') >= 0) {
        changeReg = req.clone({
          url: url + req.url,
          headers: req.headers
            .set('Authorization', token)
        });
      }
      this.progressService.show();
      return next.handle(changeReg).pipe(
        tap((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            this.progressService.hide();
          }
        }, (error) => {
          this.progressService.hide();
        })
      );
    } else {
      this.progressService.show();
      const changeReg = req.clone({ url: url + req.url});
      return next.handle(changeReg).pipe(
        tap((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            this.progressService.hide();
          }
        }, (error) => {
          this.progressService.hide();
        })
      );
    }
  }
}

只要删除你觉得多余的东西,祝你好运。

【讨论】:

  • 我必须在某处注入 cors 配置组件吗?
  • 我的角度拦截器很好。我在 spring boot 中添加了 cors config 作为组件并且它起作用了。我不知道为什么,但还是谢谢。
  • 无需将 cors 配置注入到 angular 端,如果它在生产环境中,请确保两者都在 https 或 http
  • 谢谢。我花了很多时间搜索,我什至尝试了一些我找到的 cors 过滤器,但它没有用。显然 HIGHEST_PRECENDENCE 是关键。
猜你喜欢
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 2020-08-13
  • 2022-06-17
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
相关资源
最近更新 更多