mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 11:37:08 +00:00
Improve handling of JWT over websocket.
When a valid `token` message is received from a client, the socket server will automatically push refreshed tokens at about half lifetime of the received JWT. If an invalid token is received the connection is closed. See #304.
This commit is contained in:
@@ -8,6 +8,48 @@ function start (server, pingInterval=30000) {
|
||||
|
||||
const wsServer = new ws.Server({ noServer: true });
|
||||
wsServer.on('connection', socket => {
|
||||
|
||||
function scheduleJwtRefresh (token) {
|
||||
const decoded = jwt.decode(token);
|
||||
console.log("scheduleJwtRefresh for token", token);
|
||||
console.log("decoded as", decoded);
|
||||
const exp = decoded?.exp;
|
||||
if (exp) {
|
||||
const timeout = (exp*1000 - Date.now()) / 2;
|
||||
socket._jwtRefresh = setTimeout(() => refreshJwt(token), timeout);
|
||||
console.log(`Scheduled JWT refresh in ${timeout/1000} seconds at time ${(new Date(Date.now() + timeout)).toISOString()}`);
|
||||
} else {
|
||||
console.log("Token has no exp claim. Refresh not scheduled");
|
||||
}
|
||||
}
|
||||
|
||||
function refreshJwt (token) {
|
||||
console.log("refreshJwt called");
|
||||
jwt.checkValidCredentials({jwt: token}).then( decoded => {
|
||||
console.log("refreshJwt decoded JWT = ", decoded);
|
||||
if (decoded) {
|
||||
console.log("Renewing JWT via websocket");
|
||||
delete decoded.exp;
|
||||
const token = jwt.issue(decoded);
|
||||
socket.send(JSON.stringify({
|
||||
channel: ".jwt",
|
||||
payload: {
|
||||
token
|
||||
}
|
||||
}));
|
||||
|
||||
scheduleJwtRefresh(token);
|
||||
} else {
|
||||
console.warn("FAILED to decode JWT");
|
||||
}
|
||||
})
|
||||
.catch( err => {
|
||||
console.log("refreshJwt: Invalid credentials found");
|
||||
console.error(err);
|
||||
socket.close();
|
||||
});
|
||||
}
|
||||
|
||||
socket.alive = true;
|
||||
socket.on('pong', function () { this.alive = true; })
|
||||
socket.on('message', message => {
|
||||
@@ -16,26 +58,18 @@ function start (server, pingInterval=30000) {
|
||||
try {
|
||||
const payload = JSON.parse(message);
|
||||
if (payload?.jwt) {
|
||||
jwt.checkValidCredentials({jwt: payload.jwt}).then( decoded => {
|
||||
// console.log("Decoded", decoded);
|
||||
if (decoded) {
|
||||
console.log("Renewing JWT via websocket");
|
||||
delete decoded.exp;
|
||||
const token = jwt.issue(decoded);
|
||||
socket.send(JSON.stringify({
|
||||
channel: ".jwt",
|
||||
payload: {
|
||||
token
|
||||
}
|
||||
}));
|
||||
}
|
||||
});
|
||||
refreshJwt(payload.jwt);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Websocket message decoding failed", err);
|
||||
}
|
||||
|
||||
});
|
||||
socket.on('close', () => {
|
||||
if (socket._jwtTimeout) {
|
||||
clearTimeout(socket._jwtTimeout);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
server.on('upgrade', (request, socket, head) => {
|
||||
|
||||
Reference in New Issue
Block a user