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

login event fired twice (using socketIO) #1830

Closed
SharpBCD opened this issue Feb 27, 2020 · 10 comments
Closed

login event fired twice (using socketIO) #1830

SharpBCD opened this issue Feb 27, 2020 · 10 comments

Comments

@SharpBCD
Copy link

SharpBCD commented Feb 27, 2020

Issue with V4 as well

The problem described in issue 1174 is still happening to me and I use v4.

What I get on server

Authentication successful for: xyz // console.log from authenticate
New connection request. event is: login // from handleConnection
Adding authentication information to connection: xyz // from handleConnection
New connection request. event is: login
Adding authentication information to connection: xyz
Anonymous connection request // from channels, app.on('connection',.... but the connection is known
User xyz has joined 6 channels // from channels, app.on('login',.....
User xyz @vhci.ro has joined 6 channels

And disconnect
is also fired twice.

System configuration

"@feathersjs/authentication-client": "^4.5.1",
"@feathersjs/feathers": "^4.5.1",
"@feathersjs/socketio-client": "^4.3.11",

@daffl
Copy link
Member

daffl commented Feb 27, 2020

The login event might happen whenever the socket is reconnecting. You should set your handler up in a way that multiple login events are handled the same way.

@SharpBCD
Copy link
Author

I really tried but can not found how to do it.
I implemented the handleConnection (similar with JWT, it extends AuthenticationBaseStrategy) I found duplicate login for the same connection and then? I could not find how to stop from creating another connection.

In channels I tested as well and if the connection already exist, it is not added again. Now the channels works fine but when I disconnect, I still got 2 events fired which means that I do have 2 connections at the same time.

How can I prevent this? How can I stop a connection from being created if another one already exist?

@daffl
Copy link
Member

daffl commented Feb 29, 2020

I just tested this with the feathers-chat and I am only getting a single login and disconnect event per connection. The problem might be on your frontend where you are establishing two connections for some reason.

@SharpBCD
Copy link
Author

SharpBCD commented Mar 1, 2020

That may be. I suspect it is associated with this issue 1831

but how can I prevent it from back-end? How can I stop the login event?

@daffl
Copy link
Member

daffl commented Mar 1, 2020

I don't know what your client side setup looks like but it's probably trying to set up the connection multiple times where it shouldn't. You'd need to provide a full example to reproduce the problem to know more.

@SharpBCD
Copy link
Author

SharpBCD commented Mar 2, 2020

Here is the code:

  1. Init the app js
import feathers         from '@feathersjs/feathers';
import socketio         from '@feathersjs/socketio-client';
import io               from 'socket.io-client';
import auth     from '@feathersjs/authentication-client';

// initiate IO Socket and configure
		restApi.carrySocket = io(pathStore.state.serverPath, {
			transports: ['websocket'],
			forceNew  : true
		});
		restApi.configure(socketio(restApi.carrySocket, {
			timeout     : 2000, // 2 sec is enough. Maybe...
		}));
		
		restApi.configure(auth(
			{
				header      : 'Authorization', // the default authorization header for REST
				path        : '/authentication', // the server-side authentication service path
				authStrategy: 'firebase_strategy', // the name of the JWT authentication strategy
				entity      : 'user', // the entity you are authenticating (ie. a users)
				service     : 'users', // the service to look up the entity
				// cookie are working
				locationKey : 'accessToken', // the name of the cookie to parse the JWT from when cookies are enabled server side
				cookie      : 'accessToken', // the name of the cookie to parse the JWT from when cookies are enabled server side
				storageKey  : 'accessToken', // the key to store the accessToken in localstorage or AsyncStorage on React Native
				storage     : localStorage, // Passing a WebStorage-compatible object to enable automatic storage on the client.
				scheme      : "Bearer"
			}
		));

on login page:

await restApi.authentication.setAccessToken(accessToken);
					
const serverResponse = await restApi.authenticate({
	strategy   : 'firebase_strategy',
	accessToken: accessToken
});

So maybe I don't initialize it correct?

@SharpBCD
Copy link
Author

SharpBCD commented Mar 5, 2020

Still... how can I prevent multiple session creation? I wrote the code to detect when the connection is the same but I don't know what to do when it's duplicate.

@daffl
Copy link
Member

daffl commented Mar 5, 2020

You'll have to handle that in the login event when you know the user and keep track if they are already logged in.

@SharpBCD
Copy link
Author

SharpBCD commented Mar 8, 2020

But it is said: the login event "will be sent after a user logs in". So it's too late.
Multiple attempt to login can not be completely eliminated from front-end. Situation like: disconnecting for temporary lack of internet access will trigger several attempts to reconnect. When connection to server is re-established there will be several reLogins request pending.

I tried disconnecting if the connection is already there but it's not working. I got a 'disconnect' event in front-end too, which is quite normal, actually.

So how to address this? How to cancel a login once detected that it's duplicate?

@daffl
Copy link
Member

daffl commented Mar 9, 2020

I still don't understand your problem. One connection will only trigger one reconnection attempt. You don't need to cancel any logins. As I said before, your login handlers should be written in a way that multiple same login events will end up in the same end result.

If you want to prevent multiple logins, check payload.strategy. local is used for the initial username/password login, jwt is used for every subsequent login.

@daffl daffl closed this as completed Mar 28, 2020
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