Skip to content

Commit 9db5e7a

Browse files
authored
fix(authentication-client): Improve socket reauthentication handling (#2895)
1 parent cfc6c7a commit 9db5e7a

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

packages/authentication-client/src/core.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,12 @@ export class AuthenticationClient {
6767
}
6868

6969
handleSocket(socket: any) {
70-
// Connection events happen on every reconnect
71-
const connected = this.app.io ? 'connect' : 'open'
72-
const disconnected = this.app.io ? 'disconnect' : 'disconnection'
73-
74-
socket.on(disconnected, () => {
75-
const authPromise = new Promise((resolve) => socket.once(connected, (data: any) => resolve(data)))
76-
// Only reconnect when `reAuthenticate()` or `authenticate()`
77-
// has been called explicitly first
78-
// Force reauthentication with the server
79-
.then(() => (this.authenticated ? this.reAuthenticate(true) : null))
80-
81-
this.app.set('authentication', authPromise)
70+
// When the socket disconnects and we are still authenticated, try to reauthenticate right away
71+
// the websocket connection will handle timeouts and retries
72+
socket.on('disconnect', () => {
73+
if (this.authenticated) {
74+
this.reAuthenticate(true)
75+
}
8276
})
8377
}
8478

packages/authentication-client/test/integration/socketio.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import socketioClient from '@feathersjs/socketio-client'
77
import authClient from '../../src'
88
import getApp from './fixture'
99
import commonTests from './commons'
10+
import { AuthenticationResult } from '@feathersjs/authentication/lib'
1011

1112
describe('@feathersjs/authentication-client Socket.io integration', () => {
1213
let app: Application
@@ -52,6 +53,35 @@ describe('@feathersjs/authentication-client Socket.io integration', () => {
5253
assert.strictEqual(dummy.headers.authorization, `Bearer ${accessToken}`)
5354
})
5455

56+
it('reconnects after socket disconnection', async () => {
57+
const user = { email: 'disconnecttest@example.com', password: 'alsosecret' }
58+
const socket = io('http://localhost:9777', {
59+
timeout: 500,
60+
reconnection: true,
61+
reconnectionDelay: 100
62+
})
63+
const client = feathers().configure(socketioClient(socket)).configure(authClient())
64+
65+
await app.service('users').create(user)
66+
await client.authenticate({
67+
strategy: 'local',
68+
...user
69+
})
70+
71+
const onLogin = new Promise<AuthenticationResult>((resolve) => app.once('login', (data) => resolve(data)))
72+
73+
socket.once('disconnect', () => socket.connect())
74+
socket.disconnect()
75+
76+
const {
77+
authentication: { strategy }
78+
} = await onLogin
79+
const dummy = await client.service('dummy').find()
80+
81+
assert.strictEqual(strategy, 'jwt')
82+
assert.strictEqual(dummy.user.email, user.email)
83+
})
84+
5585
commonTests(
5686
() => app,
5787
() => {

0 commit comments

Comments
 (0)