Skip to content

Instantly share code, notes, and snippets.

@philenius
Last active March 29, 2023 10:37
Show Gist options
  • Save philenius/641aebd1ba56769829e1fc7771326bf8 to your computer and use it in GitHub Desktop.
Save philenius/641aebd1ba56769829e1fc7771326bf8 to your computer and use it in GitHub Desktop.
Usage of Passport JWT Strategy for Authentication in Socket.IO
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Socket.IO with JWT Authentication</title>
</head>
<body>
<h1>Socket.IO with JWT Authentication</h1>
<textarea style="width: 300px; height: 300px"></textarea>
<br>
<button onclick="sendMessage()">Send message</button>
<!-- Imports Socket.IO client library from CDN. The version of the
client lib must match the version of the NPM package used in the
Node.js backend -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.min.js"></script>
<script>
// Initiates the Socket.IO connection to the Node.js backend
const socket = io.connect('', {
extraHeaders: {
Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMDAxIiwibmFtZSI6ImFkbWluIiwiaWF0IjoxNTE2MDQ0NDQ0fQ.aWj5grFWJwcsbgxNJ7HdfL5PUfD8fMh9GwXutuR86GE",
},
});
socket.on('connect', () => {
log('Connected to server');
});
socket.on('message', (message) => {
log(message);
})
socket.on('diconnect', () => {
log('Disconnected from server');
});
function log(message) {
document.getElementsByTagName('textarea')[0].value = document.getElementsByTagName('textarea')[0].value + '\n' + message;
}
/**
* Emits a `message` event with the payload `Hello, world` which
* is send via the WebSocket connection to the Node.js backend.
*/
function sendMessage() {
socket.emit('message', 'Hello, world');
}
</script>
</body>
</html>
{
"name": "socket-io-with-jwt-auth",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"socket.io": "^4.0.1"
}
}
'use strict';
const port = process.env.PORT || 3000;
const secret = process.env.SECRET || 'secret';
const app = require('express')();
const httpServer = require('http').createServer(app);
const io = require('socket.io')(httpServer);
const path = require('path');
const passport = require('passport');
const JWTStrategy = require('passport-jwt').Strategy;
const ExtractJWT = require('passport-jwt').ExtractJwt;
const User = require('./user-service');
function log(...args) {
console.log(new Date(), ...args);
}
passport.use(new JWTStrategy({
jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
jsonWebTokenOptions: {
ignoreExpiration: false,
},
secretOrKey: secret,
algorithms: ['HS256'],
}, (jwtPayload, done) => {
try {
const user = User.findById(jwtPayload.sub);
if (!user) {
return done(null, false);
}
return done(null, user);
} catch (error) {
return (error, false);
}
}));
passport.serializeUser(function (user, done) {
if (user) done(null, user);
});
passport.deserializeUser(function (id, done) {
done(null, id);
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'));
});
const wrapMiddlewareForSocketIo = middleware => (socket, next) => middleware(socket.request, {}, next);
io.use(wrapMiddlewareForSocketIo(passport.initialize()));
io.use(wrapMiddlewareForSocketIo(passport.authenticate(['jwt'])));
io.on('connection', (socket) => {
log('new socket connection');
socket.on('message', (message) => {
log(`Socket.IO event 'message' from client with payload: ${message}`);
socket.emit('message', `server response: ${message}`);
});
});
httpServer.listen(port, () => {
log(`Listening on http://localhost:${port}`);
});
'use strict';
module.exports = {
/**
* @param {string} userId
* @returns {{id: string, name: string}}
*/
findById: function (userId) {
return users.find(u => u.id === userId);
},
};
const users = [
{
id: '1001',
name: 'admin',
},
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment