我试图从前端到vertx后端建立sock.js连接。
我最初的尝试看起来像这样:
let token = '<the token>';
let data = {'Authorization' : 'Bearer ' + token};
let eb = new EventBus("http://localhost:8080/eventbus");
eb.onopen = function () {
eb.registerHandler('notifications', data, (err, msg) => {
// handle the response
});
}
这不起作用,因为我需要在EventBus创建时发送auth数据,即使官方的sock.js文档声明这不受支持。显然现在发送new EventBus("http://localhost:9090/eventbus", data)
也不起作用。
https://github.com/sockjs/sockjs-node#authorisation
我的后端处理程序:
final BridgeOptions bridgeOptions = new BridgeOptions()
.addOutboundPermitted(new PermittedOptions().setAddress("notifications"))
final SockJSHandler sockJSHandler = SockJSHandler.create(vertx).bridge(bridgeOptions, event -> {
event.complete(true);
});
router.route("/eventbus/*").handler(ctx -> {
String token = ctx.request().getHeader("Authorization"); // null
});
router.route("/eventbus/*").handler(sockJSHandler);
无论我尝试了什么,标题字段Authroization
始终为空。
验证sock.js连接并注册到vertx中的eventbus请求的标准方法是什么?
答案 0 :(得分:4)
SockJS默认使用WebSockets。您无法使用JavaScript WebSocket API添加自定义标头(授权等)。请阅读此thread以获取更多说明。
我看到了两种方法,如何添加授权:
只需将'disabled' => false,
'uploadURL' => "https://mywebsite.com/img/upload/",
'uploadDir' => "/home/XXXXXXX/public_html/img/upload/",
'theme' => "default",
参数添加到网址:
token
以下是如何在服务器上获取它:
let eb = new EventBus("http://localhost:8080/eventbus?token=" + token);
连接到服务器后发送授权消息。它可以是一些JSON对象,其中包含String token = ctx.request().getParam("token");
字段。
我认为,第一种选择就足够了,但是,就事件总线和SockJS而言,第二种选择可能更难实现。
答案 1 :(得分:1)
由于无法发送Authorization标头,因此可以附加令牌查询参数(如@berserkk所述)。
但是,在某些情况下,可能不希望以纯文本形式将主登录令牌作为查询参数发送,因为它比使用标头更不透明,并且最终会被记录在哪里。如果这给您带来了安全隐患,则另一种选择是仅将辅助JWT令牌用于Web套接字内容。
创建一个用于生成此JWT的REST端点,当然,只有使用您的主要登录令牌(通过标头传输)进行身份验证的用户才能访问该端点。 Web套接字JWT的配置可以与您的登录令牌不同,例如超时时间较短,因此作为升级请求的查询参数发送出去比较安全。
为注册SockJS eventbusHandler的同一路由创建一个单独的JwtAuthHandler 。确保首先注册了身份验证处理程序,以便您可以针对数据库检查Web套接字令牌(JWT应该以某种方式链接到后端的用户)。
答案 2 :(得分:0)
我认为保护Web套接字的最佳方法是使用CORS检查
跨源资源共享是一种允许请求资源的安全机制
router.route().handler(CorsHandler.create(your host origin path).allowCredentials(true));
我们还可以使用sockjs添加更多安全层:
允许事件总线桥进/出指定地址的事件
BridgeOptions opts = new BridgeOptions()
.addInboundPermitted(new PermittedOptions().setAddressRegex(Constants.INBOUND_REGEXP));