Tengo problemas para identificar a los usuarios que se han conectado con sockets web. Así es como puede reproducir este problema:
1) Cree un nuevo cliente y configure un WebSocketLink
con connectionParams
.
const wsLink = new WebSocketLink({
uri: `ws://localhost:3333`,
options: {
connectionParams: {
lazy: true,
authToken: localStorage.getItem('token')
}
}
});
En este punto, el usuario no ha iniciado sesión, no hay ningún token. El websocket tampoco se ha conectado todavía, porque lazy
está configurado como verdadero. No se conecta hasta que se envía la primera suscripción, después de que el usuario ha iniciado sesión.
Cuando el usuario inicia sesión y se ha establecido la conexión, authToken
es nulo porque este valor se estableció cuando se configuró el cliente, no después de que el usuario haya iniciado sesión.
subscriptionServer.onConnect = params => {
console.log('connected: ', params.authToken) // null
}
Las consultas y mutaciones se autorizan concatenando enlaces:
const httpLink = new HttpLink({ uri: GRAPHQL_ENDPOINT })
const authLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem('token')
if (token) {
operation.setContext({
headers: {
authorization: `bearer ${token}`
}
})
}
return forward(operation)
})
const httpAuthLink = authLink.concat(httpLink)
Puedo identificar a los usuarios de esta manera porque el token
se agrega al encabezado authorization
cuando la solicitud se ha enviado después de que el usuario ha iniciado sesión. El problema con los parámetros de conexión WebSocketLink
es que lee el token cuando el cliente se está configurando antes de que el usuario haya iniciado sesión.
He podido encontrar una solución temporal. Una vez que se identifica al usuario y se guarda su token en el navegador, actualizo la página: window.location = '/'
. Aunque se siente tan sucio.
¿Alguna idea sobre agregar los métodos onConnecting
y onDisconnect
al constructor options
del WebSocketLink
? Este enfoque evitará la necesidad de actualizar la página.
const wsLink = new WebSocketLink({
uri: `ws://localhost:3333`,
options: {
onConnecting: () => {
// Invoked just before the Socket initially connects
// returns additional connection params
return {
authToken: localStorage.getItem('token')
}
},
onDisconnect: () => {
// Invoked when the socket is disconnected
}
}
});
no hagas eso, prueba esto:
connectionParams: () => ({
lazy: true,
authToken: localStorage.getItem('token')
})
Gracias @gpbaculio
Comentario más útil
no hagas eso, prueba esto: