Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-authenticating after server disconnect #25

Open
Fiveside opened this issue Mar 10, 2016 · 7 comments
Open

Re-authenticating after server disconnect #25

Fiveside opened this issue Mar 10, 2016 · 7 comments

Comments

@Fiveside
Copy link

I've run into an interesting issue where clients do not re-authenticate after disconnections when you define an authentication callback. Specifically, if you kill the server without killing the client, then RPC calls will not complete saying authentication is still required.

@alaa-eddine
Copy link
Contributor

Hi @Fiveside
I don't get the issue :) can you please describe the case step by step ?
are you using the demo authentication code ?

@Fiveside
Copy link
Author

Hi @alaa-eddine,

I'm actually working with some code where the server calls methods on the client when they authenticate. The problem also exists with client -> server RPC, but this example is more consise and doesn't rely on setTimeout or setInterval. Here's what I'm using to reproduce the problem:

server.js

var http = require('http');
var httpServer = http.createServer();
var Eureca = require('eureca.io');

var eurecaServer = new Eureca.Server({
  allow: ["hello"],
  authenticate: function (authToken, next) {
    console.log('Called Auth with token', authToken);
    if (authToken == 'OK') next();
    else next('Auth failed');
  }
});

eurecaServer.on("connect", function(client) {
  client.clientProxy.hello("Hello").then(function(response) {
    console.log("Got response back! " + response);
  });
});

eurecaServer.attach(httpServer);
httpServer.listen(8000);

client.js

var Eureca = require('eureca.io');

var client = new Eureca.Client({
  uri: 'ws://localhost:8000/',
  autoConnect: false,
});

client.exports.hello = function(greeting) {
  return greeting + " World!";
}

client.on("authResponse", function(result) {
  console.log("auth response", result)
})

client.connect()
client.authenticate("OK")
  • Run the client and the server in separate terminals. The server's terminal should look like this:
$ node server.js
* using primus:engine.io
Called Auth with token OK
Got response back! Hello World!
  • Then, without killing the client, kill the server and restart it. The server's terminal should look like this:
$ node server.js
* using primus:engine.io
Authentication needed for  7wSzyTDBSCK5ofJCAAAA

The second time the server starts up, the client doesn't attempt to authenticate with the server. As a result, all RPC calls do not execute properly.

@alaa-eddine
Copy link
Contributor

well this behavior is "normal".
because the authentication implementation is very basic, and let the developer decide what he want to do with auth information.

when a server is killed, it lose authentication information, when it's back online it's up to you to decide what you want to do because here you have different possible use cases.
You can decide to resend the authentication request from the client for example, or close connection to force client reauthenticate

if you want to handle auto-reconnect, you need to store some information to identify connected client on some persistent storage.
when the server is back and a client tries to make a call, use a generic ensureConnection() function which will check and set authentication flag.
when the client calls a server side method, the authentication flag is this.eureca.authenticated

I can maybe add some method to the server which will explicitely consider a client as authenticated so that the developer can use it in such scenario.

When I'll have some spare time, I'll try to make an example to persist the authentication with a server kill/restart.

@Fiveside
Copy link
Author

Instead of storing client ids, it seems like it'd be more efficient to just reauthenticate on reconnection. Your comment gave me the idea that we can simply reauthenticate on connection though and this seems to work.

client.on("connect", function() {
  client.authenticate("OK");
});

On the server side, we would need to add another post-authentication call into the authentication callback function to detect when clients have successfully authenticated. This would work, but it sounds a little messy. Perhaps it might be cleaner to fire an authenticated event when clients have successfully authenticated?

@alaa-eddine
Copy link
Contributor

I'm preparing the version 0.6.5 with some optimizations and new internal features.
I'll add the authenticated event but I'm trying to figure out what will be the best solution :

  1. trigger 'authenticated' event with true/false result to tell if the auth was ok/ko
  2. trigger authSuccess when OK and authFailure when KO

I personnally prefer the first approach, but maybe I'm missing some usecase whre the second option is better ?

@alaa-eddine
Copy link
Contributor

I pushed a new version to github repository (will update the npm package later).

this version introduce 'authentication' event.
the callback have an argument taking null value on authentication success, and a different value when the authentication fail.

@Fiveside
Copy link
Author

Fantastic! I'll try it out tonight!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants