拦截(并可能拒绝)Web 套接字升级请求

Ark*_*ann 7 websocket node.js express

我有一个 Node.js 服务器,我正在向其发送 Web 套接字升级请求。此请求的授权标头包含登录信息,我需要将其与数据库条目进行比较。我不确定如何阻止 Web 套接字连接打开,直到执行数据库查询回调之后。

以下是我目前正在做的事情的简化:

var Express = require('express')
var app = Express() 
server = app.listen(app.get("port"), function () {})
server.on("upgrade", function (request, socket) {
//Query database
//On success set "authenticated" flag on request (later accessed through socket.upgradeReq)
//On failure abort connection
})
Run Code Online (Sandbox Code Playgroud)

这是可行的,但有一段短暂的时间,套接字处于打开状态,但我尚未验证授权标头,因此恶意用户可能会发送/接收数据。我通过使用“经过身份验证”标志来减轻实施中的这种风险,但似乎必须有更好的方法。

我尝试了以下操作,但是虽然它们似乎拦截了除升级请求之外的所有请求:

Attempt #1: 
app.use(function (request, response, next) {
//Query database, only call next if authenticated
next()
})

Attempt #2:
app.all("*", function (request, response, next) {
//Query database, only call next if authenticated
    next()
})
Run Code Online (Sandbox Code Playgroud)

可能值得注意的是:我也有一个 HTTP 服务器,它使用相同的端口并接受注册和登录的 POST 请求。

感谢您的帮助,如果需要更多信息,请告诉我。

Ali*_*i80 3

verifyClient就是为了这个目的而实施的!

const WebSocketServer = require('ws').Server
const ws = new WebSocketServer({
    verifyClient: (info, cb) => {
        const token = info.req.headers.token
        if (!token)
            cb(false, 401, 'Unauthorized')
        else {
            jwt.verify(token, 'secret-key', (err, decoded) => {
                if (err) {
                    cb(false, 401, 'Unauthorized')
                } else {
                    info.req.user = decoded
                    cb(true)
                }
            })
        }
    }
})

Run Code Online (Sandbox Code Playgroud)

src: 使用 JWT 和 WS 在 Node.js 中进行 Websocket 身份验证