I have a web server written in node/express which uses passport to authenticate users with JSON Web Tokens (JWT).
For regular HTTP methods this is what I use:
app.get('/api/stuff', isLoggedIn(), (req, res) => {
//get stuff
res.send( whatever );
});
Where isLoggedIn is this function:
function isLoggedIn() {
return passport.authenticate('local-jwt', { session: false });
}
The authentication itself is handled by the 'local-jwt' configuration in passport using a JWTStrategy object and it works as expected.
Now I need to add web sockets to this app. I'm using the ws library. Here is what I have so far:
const wss = new WebSocket.Server({
port: 8080,
verifyClient: async (info, done) => {
// ???
done( result );
}
});
wss.on('connection', ws => {
// web socket events
});
How do I use the passport authentication to only allow clients with the correct token to connect to the web socket server?
You can sign the token with the user's id or anything you are using to differentiate users
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);
then pass the token to the frontend and use it to initialize your Websocket connection with it appended to the url then take and decode it in the server like this
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
});
This is one of many ways. There is a way with sessions but I see you don't want to use them. Also I don't know if you use mongo but it's the same for any database you just have to change some code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With