2015-06-13 14 views
6

Ho intenzione di provare ad autenticare una connessione su socket.io.Autenticazione in Socket.io

Attualmente, l'utente viene prima autenticato tramite un'API REST, quindi, l'utente invia un JsonWebToken con il nome utente dell'utente autenticato. Dopo aver aperto la connessione tra il client e il server, il mio piano è quello di eliminare temporaneamente quel socket dall'elenco dei socket connessi per impedire la ricezione e l'invio di dati tra il server mentre eseguo l'auth.

In questa autenticazione, verifica il token e se il token è valido, aggiungo nuovamente l'ID del socket all'elenco dei socket connessi. L'unico problema è che la prima parte non funziona. Non riesco a cancellare il socket dalla lista.

Per verificare questo ho fatto quanto segue.

io.on('connection', function(socket){ 
    //temp delete socket 
    delete io.sockets.connected[socket.id]; 
    console.log(io.sockets.connected); 
    socket.emit("test"); 
}); 

Come potete vedere cancello la presa ed emettono un evento di prova per vedere se il socket è ancora aperto. Il messaggio è stato ricevuto dal client quando non dovrebbe essere.

Qualcuno sa perché questo si verifica?

+0

se la presa è ancora aperta. Quindi ascolta sempre.Prima di ciò è necessario confermare che tutta la connessione è stata chiusa. Se qualcuno di questi non chiude, il client live ascolterà. grazie. –

+0

Non si desidera disconnettere temporaneamente il socket. socket.io ha uno schema di autenticazione che puoi collegare in modo che il socket non venga mai accettato se non autentica. Tieni presente che tutte le connessioni webSocket iniziano con una richiesta http, quindi se sei già autenticato tramite http, puoi utilizzarlo anche per il webSocket. Anche l'eliminazione di un socket da 'io.socket.connected' non comporta la disconnessione del socket. – jfriend00

+0

Io uso il resto api per autenticare un utente in modo che possano usare il servizio. Per quanto ne so, posso autenticare l'utente ma non posso autenticare la sessione socket.io allo stesso modo. La mia idea era di usare i token per assicurare che la persona che usa il socket sia autenticata –

risposta

9

Prova utilizzando il metodo di disconnessione dalla oggetto socket, qualcosa di simile:

io.on('connection', function(socket){ 
    //temp delete socket 
    socket.disconnect(); 

    console.log(io.sockets.connected); 
    socket.emit("test"); 
}); 

UPDATE:

Per esempio se il vostro server HTTP consente a un client un token:

app.post('/api/users', function (req, res) { 
    var user = { 
    username: req.body.username 
    }; 

    var token = jwt.sign(user, secret, {expiresInMinutes: 30}); 

    res.json({token: token}); 
}); 

quindi puoi riutilizzare quel token per un autenticare le connessioni websocket.

Il token invio del codice da parte del cliente (file html) sarà:

socket = io.connect('http://localhost:4000', { 
    query: 'token=' + validToken, 
    forceNew: true 
}); 

e il codice di autorizzazione socketio nel server (socketio) sarà:

// here is being used a socketio middleware to validate 
// the token that has been sent 
// and if the token is valid, then the io.on(connection, ..) statement below is executed 
// thus the socket is connected to the websocket server. 
io.use(require('socketio-jwt').authorize({ 
    secret: secret, 
    handshake: true 
})); 



// but if the token is not valid, an error is triggered to the client 
// the socket won't be connected to the websocket server. 
io.on('connection', function (socket) { 
    console.log('socket connected'); 
}); 

Nota che il segreto utilizzato su express per generare un token, lo stesso token viene utilizzato anche nel token di convalida del middleware socketio.

ho creato un esempio in cui si può vedere come questo tipo di convalida funziona, il codice sorgente è qui: https://gist.github.com/wilsonbalderrama/a2fa66b4d2b6eca05a5d

copiarli in una cartella ed eseguire il server.js con nodo e quindi accedere al file html dal browser al seguente URL: http://localhost:4000

ma prima installare i moduli: socket.io, express, socketio-JWT, jsonwebtoken

+0

Come potrei riconnetterlo dopo che l'autenticazione è stata completata? Sarebbe semplice come socket.reconnect()? –

+0

Non è necessario disconnettersi prima di auth. socket.io ha il middleware di autenticazione. Si può semplicemente collegare direttamente a questo e il socket non verrà connesso in primo luogo fino a quando non si autentica. – jfriend00

+0

@WilsonBalderrama L'ho provato, ma non ho potuto farlo funzionare tramite questo framework per iOS. https://github.com/socketio/socket.io-client-swift. Il problema era che avrei ricevuto un errore senza intestazioni inviate ogni volta. –

0

socket.io salva anche le prese in uno spazio dei nomi (di default se non specificato) e qui è dove devi cancellarlo perché smetta di ricevere messaggi.

Vedere this post per una spiegazione passo passo di ciò che si sta tentando di fare e this module che riassume l'intero processo.