403 被禁止

问题描述 投票:0回答:1

我使用AWS的websocket API网关创建了一个Websocket API。创建 api 后,我得到了这样的端点

wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev

我可以直接使用它并调用

$connect
lambda,没有任何问题

现在我希望通过 Cloudfront 提供服务。

我已经有一个具有备用域名(如

app.blablabla.cloud
)的发行版,它为不同的服务提供多个 REST API(源类型:API 网关)。我也想对 websocket API 做同样的事情

我为发行版创建了一个新的自定义源

  • 原始域名 -
    x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com
  • 协议 - 仅限 HTTPS
  • HTTPS 端口 - 443
  • 最小来源 SSL 协议 - TLS v1
  • 原点路径 - 留空
  • 其余配置 - 默认

之后我创建了一个行为并附加了这个起源

  • 路径图案 -
    /dev/my-socket/*
  • 自动压缩对象 - 是
  • 查看器 - 仅限 HTTPS
  • 允许的 HTTP 方法 - GET、HEAD、OPTIONS、PUT、POST、PATCH、DELETE
  • 限制查看者访问 - 否
  • 缓存密钥和源请求 - 缓存策略和源请求策略
    缓存策略 - CachingDisabled
    源请求策略 - 使用
    Cookies - All
    Query strings - All
    Headers - Include the following headers - Sec-WebSocket-Key, Sec-WebSocket-Version, Sec-WebSocket-Protocol, Sec-WebSocket-Accept, Sec-WebSocket-Extensions
  • 创建策略
  • 其余配置 - 默认

现在我尝试使用 url 调用来自邮递员的 wss 初始调用

wss://app.blablabla.cloud/dev/my-socket/?param1=1&param2=test

但我得到

Status Code: 403 Forbidden
(我期待着
101 Switching Protocols
)并且请求标头是

Sec-WebSocket-Version: 13
Sec-WebSocket-Key: TVMDG46dqkDM4a7DoM20ZB==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: app.blablabla.cloud

所以看起来 Cloudfront 受到了打击,只是无法通过。 api 网关仪表板还显示了类似的内容

我不明白问题出在哪里。非常感谢您的帮助。预先感谢!

amazon-web-services websocket aws-api-gateway amazon-cloudfront http-status-code-403
1个回答
0
投票

问题是

 API Gateway’s WebSocket API does not support a path parameter in the connection URL. By design (or say it a design oversight), the connection URL path is fixed to the root path / (stage would be prepended when execute-api endpoint is used).
,如这篇中等文章中所述。

简单来说,尝试连接

wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev/my-socket/?param1=1&param2=test
将给出相同的 403 Forbidden 。只有
wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev/?param1=1&param2=test
wss://x5g9h3p2rq.execute-api.eu-central-1.amazonaws.com/dev?param1=1&param2=test
有效。

所以方法1

  • 在行为更改中路径模式 -
    /dev
    并降低优先级,以便其余的
    dev/stuff/*
    不受影响。
  • 现在我可以做
    wss://app.blablabla.cloud/dev?param1=1&param2=test

但这不可扩展。如果我们需要另一个套接字 API 该怎么办?我们不能对所有事情都使用相同的

/dev

这会带来更好的方法 2

使用Lambda@Edge

  • 保持路径模式的行为 -
    /dev/my-socket/*
  • 创建 Lambda@Edge 并将其与 Origin 请求
  • 关联
  • lambda 很简单,只需将
    uri
    /dev/my-socket/
    更改为
    /dev
'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  request.uri = request.uri.replace(/\/[^\/]+\/$/, '');
  return callback(null, request);
};

  • 现在我可以执行
    wss://app.blablabla.cloud/dev/my-socket/?param1=1&param2=test
    并且它将剥离
    my-socket
    并转发到正确的原点。
  • 此外,Lambda 仅在连接调用期间被调用。握手完成后,Lambda 不再参与。
  • 还注意到,与直接使用 API 网关 URL 相比,这种方法有轻微的延迟
© www.soinside.com 2019 - 2024. All rights reserved.