为 OPTIONS 请求添加认证。

28

如何在跨域API的OPTIONS请求中添加标题?

我正在使用的API要求在所有请求中设置JWT令牌作为Authorization标头。

当我尝试访问API时,Angular首先执行一个OPTIONS请求,这个请求不关心我为"真实"请求设置的标题,就像这样:

this._headers = new Headers({
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Bearer my-token-here'
});

return this._http
            .post(AppConfig.apiUrl + 'auth/logout', params, {headers: this._headers})
            ...
            ...
当未提供令牌时,API返回HTTP状态401,Angular认为OPTIONS请求失败。
3个回答

58
根据CORS规范,在执行预检请求时,用户凭证将被排除在外。具体而言,请参见规范
引用如下:

(...) 使用OPTIONS方法,并满足以下附加限制:

  • (...)
  • 排除作者请求标头。
  • 排除用户凭证。
  • (...)
(强调是我的) 鉴于此,问题似乎出现在API方面,API应该接受不需要身份验证的OPTIONS请求。

源已经是一个活标准,不再有引用的文本。这个答案在2021年仍然正确吗? - haz
4
目前,在第3.2.5节中提到(https://fetch.spec.whatwg.org/#cors-protocol-and-credentials):“请注意,即使如此,CORS预检请求也永远不会包含凭据。” - João Angelo
1
谢谢。我在寻找“用户凭据”这个词汇,但非常困惑。同时,我也不太擅长阅读英语。 - haz

1
如果您正在使用Cloudformation模板,您需要像下面的示例一样将AddDefaultAuthorizerToCorsPreflight声明为false
MyApiGateway:
  Type: AWS::Serverless::Api
  Properties:
    StageName: !Ref Stage
    Auth:
      Authorizers:
        CognitoAuthorizer:
          UserPoolArn: !GetAtt UserPool.Arn
      DefaultAuthorizer: CognitoAuthorizer
      AddDefaultAuthorizerToCorsPreflight: false
    Cors:
      AllowMethods: "'POST,OPTIONS'"
      AllowHeaders: "'Access-Control-Allow-Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with,x-requested-for'"
      AllowOrigin: "'*'"

这将允许OPTIONS请求接受没有授权头的请求。

-2

可以使用withCredentials选项为CORS预检请求提供身份验证:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor() {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      withCredentials: true
    });
    return next.handle(request);
  }
}

另请参阅:

https://dev59.com/IVkT5IYBdhLWcg3wbO8g#38615675


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接