Token Update
How to update or revoke tokens for authenticated usersThe token that is issued in a connection token event
1 helps services to determine what resources the connection should have access to. But sometimes a user’s access may change as they are granted new, or denied previous, permissions. Or maybe the user is kicked out, and should have their access revoked all together.
In order to update or revoke tokens, the RES protocol provides a way to identify tokens, and request for them to be updated. Let’s learn how to do this.
Token ID
In Chapter 7 - Access Control, we learned how to issue an access token for a connection, using a connection token event1. The event body has two properties:
token
- access token for the connection.tid
- optional token ID used to update/revoke a token.
By setting the tid
, token ID, property to a value that identifies the user, such as the user ID or username, we can later update or revoke that token.
In code we can set a token like this:
nats.publish("conn." + cid + ".token", JSON.stringify({
"token": {
"userId": 42,
"role": "guest"
},
"tid": "42"
}));
Note
If the service uses a numeric user ID (eg.
42
), thetid
value must be the string representation of that ID (eg."42"
).
Updating or revoking a token
Whenever a service wants to update one or more tokens, it can send a system token reset event2 where it includes a list of all the affected token IDs. This will trigger Resgate(s) to send auth requests3 for all connections with a matching token ID.
Subject
The subject of the event is:
system.tokenReset
Event message
The event message is a JSON object containing the following properties:
tids
- an array of token ID (tid) strings.subject
- a NATS subject to which Resgate(s) should send their auth requests3.
Tip
The NATS subject doesn’t have to follow the naming pattern of an actual auth request handler.
In the example below, instead of:
auth.authservice.logout
the subject could be any valid NATS subject:
clearMyToken
Example
Revoking the token for user 42 could look like this:
// Auth request handler for clearing/revoking tokens.
nats.subscribe('auth.authservice.logout', (msg, reply) => {
// Parse out the connection ID (cid).
let { cid } = JSON.parse(msg);
// Clear the token for this connection.
nats.publish("conn." + cid + ".token", JSON.stringify({
"token": null
}));
// Send successful response.
// Resgate discards results from system.tokenReset auth requests.
nats.publish(reply, JSON.stringify({
"result": null
}));
});
// Send system.tokenReset event to update/clear the token of user 42
nats.publish("system.tokenReset", JSON.stringify({
"tids": [ "42" ],
"subject": "auth.authservice.logout"
}));
Tip
The auth request also contains all the other info, such as header
and token
, which may be used for creating a new token, instead of clearing it:
let { cid, header, token } = JSON.parse(msg);