如何在JWT中使用node、ws和passport进行身份验证?

de90aj5v  于 2023-08-04  发布在  Node.js
关注(0)|答案(2)|浏览(119)

我有一个用node/express编写的Web服务器,它使用passport通过JSON Web Tokens(JWT)对用户进行身份验证。
对于常规的HTTP方法,这是我使用的:

app.get('/api/stuff', isLoggedIn(), (req, res) => {
    //get stuff
    res.send( whatever );
});

字符串
其中isLoggedIn是这个函数:

function isLoggedIn() {
    return passport.authenticate('local-jwt', { session: false });
}


身份验证本身是由passport中的'local-jwt'配置使用JWTStrategy对象处理的,它按预期工作。
现在我需要添加Web套接字到这个应用程序。我正在使用ws库。以下是我到目前为止所做的:

const wss = new WebSocket.Server({
    port: 8080,
    verifyClient: async (info, done) => {
        // ???
        done( result );
    }
});

wss.on('connection', ws => {
    // web socket events
});


如何使用passport身份验证只允许具有正确令牌的客户端连接到Web Socket服务器?

pieyvz9o

pieyvz9o1#

您可以使用用户ID或任何用于区分用户的内容sign令牌

var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);
jwt.sign({
        id: user._id,
        exp: parseInt(exp.getTime() / 1000),
    }, secret);

字符串
然后将令牌传递给前端,并使用它来初始化WebSocket连接,并将其附加到url中,然后在服务器中像这样获取并解码它

const wss = new WebSocket.Server({
  verifyClient: async (info, done) => {
    console.log(info.req.url);
    console.log('------verify client------');

    const token = info.req.url.split('/')[1];
    var decoded = jwt.verify(token, secret);

    info.req.user = await User.findById(decoded.id).exec();

    /*info.req.user is either null or the user and you can destroy the connection
     if its null */

    done(info.req);
  },
  server
});


这是许多方法中的一种。有一种方法与会议,但我看到你不想使用它们。另外,我不知道你是否使用mongo,但它对任何数据库都是一样的,你只需要修改一些代码。

xnifntxz

xnifntxz2#

只是在C.Gochev的answer上进行扩展,并为登陆的人提供一些考虑:
1.不鼓励使用verifyClient,以便在HTTP服务器的“升级”事件中处理客户端身份验证。有关更多信息,请参阅文档和#377。
1.更好的安全做法是使用cookie,而不是将身份验证令牌(或任何敏感信息)作为URL参数/查询发送,以减轻通过浏览器历史记录、referer标头、网络监控/日志工具等暴露身份验证令牌的风险。Herews中的一个例子,它使用了会话cookie(用express-session抽象出来)。

相关问题