为 withCredentials 指定 CORS 标头:true

Posted

技术标签:

【中文标题】为 withCredentials 指定 CORS 标头:true【英文标题】:Specifying CORS headers for withCredentials: true 【发布时间】:2018-10-19 00:04:37 【问题描述】:

我需要指定 CORS 标头,因为我需要在每个请求中发送 cookie 密钥。我在不同的服务器上有一个带有 Java Spring Boot 的后端和带有 Angular 5 的 UI。

在 UI 方面,我使用下一个 TS 代码调用服务器:

@Injectable()
export class CoreApi 
  private baseUrl = 'http://localhost:8080/rest/';

  constructor(public http: HttpClient) 
  

  public get(url: string = ''): Observable<any> 
    return this.http.get(this.getUrl(url),  withCredentials: true );
  

  public post(url: string, data: any = ): Observable < any > 
    return this.http.post(this.getUrl(url), data,  withCredentials: true );
  

  private getUrl(url: string = ''): string 
    return this.baseUrl + url;
  

我需要withCredentials: true 来发送cookie,否则Spring Security 无法识别没有会话ID 的用户。但是在服务器上,我设置了response.setHeader("Access-Control-Allow-Origin", "*"),以便在 UI 和后端使用两个不同的服务器。

我陷入了一个恶性循环:如果我删除Access-Control-Allow-Origin - *,我会得到:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

如果我删除 withCredentials: true 没有会话 ID,Spring Security 将无法正常工作。认证后的所有请求 - UNAUTHORIZED 没有 cookie。

我认为需要实施一个来源白名单,并在涉及凭据时使用有效来源响应 CORS 请求。但如何做到这一点? 如果你知道这件事,请告诉我。谢谢!

可能是这样的过滤器:

@WebFilter(urlPatterns = "/*" )
public class CorsRestFilter implements Filter 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        ...somehow sfecifying Access-Control-Allow-Origin...
        response.setHeader("Access-Control-Allow-Methods", "POST, GET");
        chain.doFilter(req, res);
    

【问题讨论】:

当你说 CROS 时,你是指 CORS 吗? @Andreas 是的,这是我的错误。谢谢你的评论。我修好了。 @user3624390 Spring Security 拒绝我的请求 (((Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403. 也许我在错误的地方添加了这个表达式...也许存在全局配置的地方。 这里很好地解释了如何设置请求标头和 cors 过滤器:***.com/questions/8685678/… 【参考方案1】:

创建常量服务组件并在服务方法调用中注入 例如:

service.ts

const httpOptions = 
  headers: new HttpHeaders( 'Content-Type': 'application/json' ),
  withCredentials: true,
;



demoServiceMethod(requestparameter): Observable<PayloadResponse<any>> 
    return this.http.post<PayloadResponse<any>>(environment.baseurl +
      'v1/test/api', requestparameter, httpOptions)
      .pipe(catchError(this.apiErrorService.handleError<PayloadResponse<any>>('operation name  ')));
  

【讨论】:

这与问题有什么关系。角度部分似乎工作正常。问题更多是关于 java 方面的事情。【参考方案2】:

您还需要添加Access-Control-Allow-Origin 标头。

response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");

如果您使用凭据进行跨源调用,则需要添加显式主机而不是 *。否则浏览器会屏蔽你的通话。

-

如果你使用的是 spring,你也可以使用他们的 crossorigin 标签: https://spring.io/guides/gs/rest-service-cors/

【讨论】:

以上是关于为 withCredentials 指定 CORS 标头:true的主要内容,如果未能解决你的问题,请参考以下文章

CORS $.ajax 会话 cookie(访问控制允许凭据和 withCredentials=true)

Angular 4 - 在每个请求上设置 withCredentials - cors cookie

xhr.withCredentials与 CORS 什么关系

xhr.withCredentials与 CORS 什么关系

CORS withCredentials XHR 预检未在 Firefox 中发布 Cookie

CORS-接口跨域问题withCredentials