当前位置: 首页 > 知识库问答 >
问题:

java - netty4 websocket 响应返回401,浏览器没有任何反应?

诸福
2024-03-18

我在使用netty开发websocket服务器,浏览器使用var socket = new WebSocket("ws://127.0.0.1:18080/ws?token=xxxx");连接时服务器将验证token,如果不通过则返回401并关闭socket。
服务器响应代码:

    private void httpResponse401(ChannelHandlerContext ctx, FullHttpRequest request){        FullHttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.UNAUTHORIZED);        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, 0);        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);        ReferenceCountUtil.release(request);    }

目前情况是socket虽然关闭,但浏览器好像没有收到401的响应。我需要在浏览器种能知道连接关闭是因为401还是其他什么情况。
image.png
image.png

共有1个答案

孙绍辉
2024-03-18

问题中的关键在于 WebSocket 连接与 HTTP 连接之间的差异。当你使用 WebSocket API (new WebSocket(...)) 连接到服务器时,你实际上正在建立一个持久的双向连接,不同于传统的 HTTP 连接。这意味着 WebSocket 连接并不遵循标准的 HTTP 响应代码(如 401)。

WebSocket 连接一旦建立,服务器不能通过发送 HTTP 响应代码来关闭连接。因此,在你的代码中,尽管你发送了一个 401 响应并关闭了连接,浏览器可能并没有正确地识别这个响应,因为它不符合 WebSocket 的协议。

如果你想在 WebSocket 连接中处理身份验证,你应该在你的应用程序协议中定义一种方式来传达身份验证失败。这通常意味着在 WebSocket 连接建立后,你需要定义一种消息格式,让服务器能够发送一个特殊的消息,告知客户端身份验证失败,然后客户端可以据此关闭连接。

例如,你可以在 WebSocket 握手成功后,发送一个包含身份验证信息的消息给服务器。如果服务器验证失败,它可以发送一个特定的消息(如一个包含错误码的消息)给客户端,然后客户端可以根据这个消息来关闭 WebSocket 连接。

以下是一个简单的例子:

服务器端

// 假设你有一个处理 WebSocket 消息的方法public void handleWebSocketMessage(ChannelHandlerContext ctx, TextWebSocketFrame frame) {    String message = frame.text();    // 解析消息并验证 token    if (!validateToken(message)) {        // 发送一个表示身份验证失败的消息        ctx.writeAndFlush(new TextWebSocketFrame("ERROR: 401 Unauthorized"));        ctx.close();    } else {        // 处理正常消息    }}

客户端

var socket = new WebSocket("ws://127.0.0.1:18080/ws?token=xxxx");socket.onmessage = function(event) {    var message = event.data;    if (message.startsWith("ERROR:")) {        // 解析错误消息并处理        var errorCode = message.split(":")[1];        if (errorCode === "401") {            console.log("WebSocket connection closed due to unauthorized access.");            socket.close();        }    } else {        // 处理正常消息    }};

这样,当服务器发送一个表示身份验证失败的消息时,客户端就可以捕获到这个消息,并据此关闭 WebSocket 连接。

 类似资料:
  • 我在等待URL更改时得到以下错误。 这个问题是断断续续的,我并不总是得到错误。因此,如果我简单地说,它就通过了。我想这与多次调用它有关,就像它在expctedconditions中所做的那样。

  • 我得到错误:com.microsoft.sqlserver.jdbc.SQLServerException:驱动程序无法通过使用安全套接字层(SSL)加密建立到SQL服务器的安全连接。错误:“SQL服务器没有返回响应。连接已关闭。” Hibernate配置: application.properties: pom.xml: SQLServerException: openssl客户端连接服务器:1

  • 我尝试使用ETAG从api请求缓存json响应。我调用类似http://localhost:3000/api/config的代码,并获取: Thx响应。

  • 问题内容: 我正在使用Java访问HTTPS站点,该站点以XML格式返回显示内容。我在URL本身中传递了登录凭据。这是代码片段: 我正在程序中创建一个不验证签名/未签名证书的信任管理器。但是,在运行上面的程序时,出现错误服务器返回HTTP响应代码:401表示URL:https:// Administrator:Password @ localhost:8443 / abcd 我可以在浏览器中使用相

  • 我有一个ReST API到一个应用程序,该应用程序中的所有控制器都在下找到,这些控制器都返回JSON响应,并带有一个,它处理所有异常以映射到JSON格式的结果。 从Spring 4.0开始,这非常有效现在支持注释匹配。我无法解决的是如何为401-UnAuthated和400-Bad Request响应返回JSON结果。 相反,Spring只是将响应返回给容器(tomcat),该容器将其呈现为超文本

  • 问题内容: 我正在通过jQuery的getJson()调用跨域Web服务。由于响应对象的大小很大,因此我在Web服务中使用了最大的JSon大小。我已经检查过getJson()提供正确的响应对象。但是仍然没有调用我的回调函数。Firebug表示已超过(firefox)响应大小。 谁能告诉我标准浏览器(例如,Firefox)处理的最大浏览器响应大小限制是多少,以及如何处理该问题? 这是相同的代码段。