WebSocket⚓︎
The nextAuth Server features a WebSocket interface which exposes the session status and has support for a limited number of actions. For instance, it can be used to dynamically update user interfaces or to listen for session status changes server-side, without having to execute API calls repeatedly.
Commands⚓︎
The following table documents the different commands which are sent to and received from the server. Commands are always encoded as strings and are formatted as {Type} {HSID} {Server ID}
, with the HSID and Server ID fields taking base64-url-encoded values.
Type | Direction | Description |
---|---|---|
REGISTER |
Client Server | This command should be sent to receive status updates for the specified session (i.e., the LOGIN , LOGOUT , and CANPROVOKE commands). |
CONFIRMSCAN |
Server Client | The client has successfully scanned and processed a presented QR code. |
LOGIN |
Server Client | The specified session is logged in. You will receive either a LOGIN or LOGOUT command in response to REGISTER . |
LOGOUT |
Server Client | The specified session is logged out. You will receive either a LOGIN or LOGOUT command in response to REGISTER . |
CANPROVOKE |
Server Client | It is possible to provoke a login for the specified session, which can be requested through the PROVOKE command. |
PROVOKE |
Client Server | Provoke a login for the specified session by sending a push command to the linked device. |
CONFIRMPROVOKE |
Server Client | The login push message has been processed by the client. |
CANCEL |
Server Client | The user aborted the authentication flow (Authentication Server >= v2.1.2, Android SDK >= v1.1.4, and iOS SDK >= v1.1.2). |
LOGOUT |
Client Server | Log out the specified session. |
NOACCOUNTS 1 |
Server Client | The user scanned a login QR code (or followed a login deep link) but has no accounts registered in the app for this server (Authentication Server >= v2.2.2, Android SDK >= v1.1.7, and iOS SDK >= v1.2.1). |
For instance, you would send the following string to the server in order to start receiving status updates, with the listed server reply for a provokable inactive session.
-> REGISTER {HSID} {Server ID}
<- LOGOUT {HSID} {Server ID}
<- CANPROVOKE {HSID} {Server ID}
JavaScript⚓︎
To set up the WebSocket and handle the changes in the LoginStatus
of the session, one can use the javascript below, replacing serverid
, hsid
and loggedin
with the correct values in the init
function. This script will reload the current page on receiving a LOGIN
(when the current status is false - logged out), or redirect to the main page on receiving a LOGOUT
(when the current status is true - logged in). You get the loggedin
and hsid
values you need through the getSession API calls.
<script>
var nextAuth = (function() {
var wssocket;
var wssocketerror;
var wssocketdisabled;
return {
init: function(){
nextAuth.wsinit([['serverid', 'hsid', loggedin]], 'wss://ws.nextauth.com/');
},
wsinit: function(sessiondata, host) {
serverid = sessiondata[0][0];
nonce = sessiondata[0][1];
wssocketerror = true;
wssocketdisabled = false;
// test websocket support
if ('WebSocket' in window || 'MozWebSocket' in window) {
window.setInterval(nextAuth.wscheck, 500, sessiondata, host);
}
},
logmsg: function(msg) {
if (typeof console !== "undefined") {
console.log("nextAuth - " + msg);
}
},
wscheck: function(sessiondata, host) {
if (!wssocketerror)
return;
if (wssocketdisabled)
return;
wssocketerror = false;
try {
if ('WebSocket' in window) {
wssocket = new WebSocket(host);
} else if ('MozWebSocket' in window) {
wssocket = new MozWebSocket(host);
}
nextAuth.logmsg('WebSocket - Status ' + wssocket.readyState);
wssocket.onopen = function(msg) {
nextAuth.logmsg("Connected");
for (var i = 0; i < sessiondata.length; i++) {
nextAuth.wssend("REGISTER " + sessiondata[i][1] + " " + sessiondata[i][0]);
}
};
wssocket.onmessage = function(msg) {
nextAuth.logmsg("Received: " + msg.data);
nextAuth.wsreceive(msg.data, sessiondata);
};
wssocket.onclose = function(msg) {
nextAuth.logmsg("Disconnected");
wssocketerror = true;
};
} catch (e) {
nextAuth.logmsg(e);
wssocketerror = true;
}
},
wssend: function(msg) {
try {
wssocket.send(msg);
nextAuth.logmsg('Sent: ' + msg);
} catch (e) {
nextAuth.logmsg(e);
}
},
getsession(sessiondata, serverid, nonce){
for (var i = 0; i < sessiondata.length; i++){
if (sessiondata[i][0] == serverid && sessiondata[i][1] == nonce){
return i;
}
}
return -1
},
wsreceive: function(msg, sessiondata) {
parts = msg.split(" ");
cmd = parts[0];
if (cmd == "LOGOUT") {
serverid = parts[2];
nonce = parts[1];
i = this.getsession(sessiondata, serverid, nonce);
if (i >= 0) {
knownstatus = sessiondata[i][2];
if (knownstatus == 1){
// currently logged in, received logout
wssocketdisabled = true; // kill the socket
if (typeof nextauthwsdoupdate == 'function')
nextauthwsdoupdate(0, serverid, nonce, i);
else
window.location.assign("/");
}
}
} else if (cmd == "LOGIN") {
serverid = parts[2];
nonce = parts[1];
i = this.getsession(sessiondata,serverid,nonce);
if (i >= 0) {
knownstatus = sessiondata[i][2];
if (knownstatus != 1) {
// currently logged in, received logout
wssocketdisabled = true; // kill the socket
if (typeof nextauthwsdoupdate == 'function')
nextauthwsdoupdate(1, serverid, nonce, i);
else
window.location.reload();
}
}
} else if (cmd == "CANPROVOKE") {
serverid = parts[2];
nonce = parts[1];
nextAuth.wscanprovoke(serverid,nonce);
if (typeof nextauthwscanprovoke == 'function') {
nextauthwscanprovoke(serverid,nonce);
}
} else if (cmd == "CONFIRMPROVOKE") {
serverid = parts[2];
nonce = parts[1];
nextAuth.wsprovokeconfirm(serverid,nonce);
if (typeof nextauthwsprovokeconfirm == 'function') {
nextauthwsprovokeconfirm(serverid,nonce);
}
}
}
}
})();
nextAuth.init();
</script>
Note that this script can listen to multiple sessions, possibly at different servers and nonces. Simply add another ['serverid', 'hsid', loggedin]
to the first parameter of nextAuth.wsinit
inside the init
function. In that case, one should implement a nextauthwsdoupdate(x, serverid, nonce, i)
function, with x
being either 0 (logout) or 1 (login) to do proper session-based handling.
-
Since the login QR code (or deep link) does not contain the data needed for the SDK to connect with your nextAuth server instance, this will need to be specified in the mobile SDK configuration. ↩