我正在处理的应用程序中遇到了 CORS 问题。
它在 Kubernetes 中设置,带有第三方 Java 框架:
http://www.ninjaframework.org/
我收到以下错误:
Preflight response is not successful
XMLHttpRequest cannot load https://api.domain.com/api/v1/url/goes/here? due to access control checks.
Failed to load resource: Preflight response is not successful
我认为问题不在于 Kubernetes,但以防万一——这是我的 Kubernetes 设置:
apiVersion: v1
kind: Service
metadata:
name: domain-server
annotations:
dns.alpha.kubernetes.io/external: "api.domain.com"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-2:152660121739:certificate/8efe41c4-9a53-4cf6-b056-5279df82bc5e
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
type: LoadBalancer
selector:
app: domain-server
ports:
- port: 443
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: domain-server
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 3
revisionHistoryLimit: 10
template:
metadata:
labels:
app: domain-server
spec:
containers:
- name: domain-server
image: "location.aws.etc"
imagePullPolicy: Always
...
我完全迷路了——如何在我的 api 端点上启用 CORS?如果这是一个简单的问题,或者我在这里没有提供足够的信息,我很抱歉,但我不知道如何做到这一点,我已经尝试了几种途径。
请注意,为了清楚起见,api.domain.com 是我实际 api 域的替代品,我只是不想透露我正在处理的网站
编辑:
我的猜测是它可能与此有关:
private Result filterProtectedApi(FilterChain chain, Context context, boolean isMerchant, JwtAuthorizer jwtAuthorizer) {
String authHeader = context.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return this.forbiddenApi();
}
context.setAttribute("access-token", authHeader.substring("Bearer ".length()));
return this.filterProtected(chain, context, isMerchant, jwtAuthorizer, parser -> parser.parseAuthHeader(authHeader), this::forbiddenResource);
}
private AuthLevel getAuthLevel(String requestPath) {
log.info("REQUEST PATH: " + requestPath);
if (requestPath.equals("/auth") || requestPath.equals("/auth/merchant") || requestPath.equals("/auth/app")
|| requestPath.startsWith("/assets/") || requestPath.equals("/privacy-policy.html")
|| requestPath.equals("/forbidden.html") || requestPath.equals("/favicon.ico")
|| requestPath.startsWith("/invite/ios/") || requestPath.startsWith("/stripe/")
|| requestPath.startsWith("/chat")) {
return AuthLevel.UNPROTECTED_RESOURCE;
}
if (requestPath.startsWith("/merchant/api/")) {
return AuthLevel.PROTECTED_MERCHANT_API;
}
if (requestPath.startsWith("/merchant/")) {
return AuthLevel.PROTECTED_MERCHANT_RESOURCE;
}
if (requestPath.startsWith("/api/")) {
return AuthLevel.PROTECTED_API;
}
return AuthLevel.PROTECTED_RESOURCE;
}
我尝试添加一些内容来忽略 OPTIONS 请求,但我仍然无法通过预检检查
private Result filterProtectedApi(FilterChain chain, Context context, boolean isMerchant,
JwtAuthorizer jwtAuthorizer) {
if (context.getMethod().toLowerCase().equals("options")) {
return chain.next(context);
}
String authHeader = context.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return this.forbiddenApi();
}
context.setAttribute("access-token", authHeader.substring("Bearer ".length()));
return this.filterProtected(chain, context, isMerchant, jwtAuthorizer,
parser -> parser.parseAuthHeader(authHeader), this::forbiddenResource);
}
我需要做什么才能使预检检查成功?
编辑 - 根据以下建议将其更改为:
@Override
public Result filter(FilterChain chain, Context context) {
if (context.getMethod().toLowerCase().equals("options")) {
return Results.html().addHeader("Access-Control-Allow-Origin", "*")
.addHeader("Access-Control-Allow-Headers", "Authorization")
.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS").render("OK");
}
AuthLevel authLevel = this.getAuthLevel(context.getRequestPath());
switch (authLevel) {
case PROTECTED_API: {
return this.filterProtectedApi(chain, context, false, this.jwtAuthorizer);
}
case PROTECTED_MERCHANT_RESOURCE: {
return this.filterProtectedResource(chain, context, "merchant-access-token", "/auth/merchant", true,
this.merchantJwtAuthorizer);
}
case PROTECTED_MERCHANT_API: {
return this.filterProtectedApi(chain, context, true, this.merchantJwtAuthorizer);
}
case UNPROTECTED_RESOURCE: {
return this.filterUnprotectedResource(chain, context);
}
}
return this.filterProtectedResource(chain, context, "access-token", "/auth", false, this.jwtAuthorizer);
}