diff --git a/docs/Client.md b/docs/Client.md index a0c11c2f..6b36f626 100644 --- a/docs/Client.md +++ b/docs/Client.md @@ -18,6 +18,7 @@ - [client.unsubscribe (unsubscriptions, [callback])](#clientunsubscribe-unsubscriptions-callback) - [client.close ([callback])](#clientclose-callback) - [client.emptyOutgoingQueue ([callback])](#clientemptyoutgoingqueue-callback) + - [client.userdata](#clientuserdata) ## new Client(aedes, stream, request) @@ -154,3 +155,21 @@ Clear all outgoing messages (QoS > 1) related to this client from persistence [websocket-stream]: https://www.npmjs.com/websocket-stream [websocket-stream-doc-on-the-server]: https://github.com/maxogden/websocket-stream/blob/master/readme.md#on-the-server + +## client.userdata + +Aedes will not create or use client.userdata - so this is safe to create if you need to store your own data against client. + +Examples of possible use: authenticating by JWT (store the decoded JWT data here), capture the IP address of the client, store additional statistics. + +As the client is available in most callbacks, this may be useful. Beware client can be null in some callbacks for internal publish ($SYS). + +``` +client.userdata = { + ip: clientip, + data: { + write:[ 'path/allowed/publish' ], + read:[ 'path/allowed/subscribe' ] + } +} +``` diff --git a/docs/Examples.md b/docs/Examples.md index 808888af..b46a709e 100644 --- a/docs/Examples.md +++ b/docs/Examples.md @@ -109,3 +109,49 @@ In order to use Aedes in clusters you have to choose a persistence and an mqemit [mqemitter-redis]: https://www.npmjs.com/mqemitter-redis [mqemitter-mongodb]: https://www.npmjs.com/mqemitter-mongodb [mqemitter-child-process]: https://www.npmjs.com/mqemitter-child-process + +## Client userdata + +The tag `userdata` on the client structure is free for use by users to store whatever they want. + +
+ Example snippet which uses JWT authentication, and captures the client ip address: + +``` + broker.authenticate = (client, username, password, callback)=>{ + username = (username || ''); + password = (password || '').toString(); + let allow = false; + client.userdata = {}; + if ((username === 'jwt')){ + try { + var token = jwt.verify( password, secret ); + // store token away for future use + client.userdata.token = token; + allow = true; + } catch(e) { + console.log('invalid jwt'); + } + } + if (allow){ + if (client.conn && client.conn.remoteAddress){ + client.userdata.ip = client.conn.remoteAddress; + } + if (client.req){ + if (client.req.socket){ + client.userdata.ip = client.req.socket.remoteAddress; + } + if (client.req.rawHeaders){ + for (let i = 0; i < client.req.rawHeaders.length; i++){ + if (client.req.rawHeaders[i] === 'x-forwarded-for'){ + client.userdata.ip = client.req.rawHeaders[i+1]; + } + } + } + } + } + callback(null, allow); + } +``` + +