nathantsoi / vue-native-websocket

native websocket with vuex integration
944 stars 162 forks source link

JSON Web Token #45

Open Laurentmichel4irulez opened 6 years ago

Laurentmichel4irulez commented 6 years ago

Can vue-native-websocket be used in combination with JSON Web Token for authentication?

elliottross23 commented 6 years ago

+1 I'm trying to implement this right now too

stremovskyy commented 6 years ago

+1 Any luck?

elliottross23 commented 6 years ago

So here's what I found. native Websockets don't support custom headers BUT the way around it would be to append your token as a query string parameter when creating the Websocket. Something like:

const myJWT = 'some-token';
const ws = new WebSocket('ws://localhost:8080?token=' + myJWT);

Since the first call to your server will be an HTTP Upgrade request, you can parse the token out and verify it. If you store your token as a cookie, there's no need to append it to the url since it will be sent with the request automatically.

I have sort of a special case since my users are already connected before they login. Because of this, I setup an "auth" message that the WebSocket will push to once they login. Just another way to verify the token.

I'm using NodeJS with the ws websockets library and here is my connection method

// --> socket is the created socket
// --> request is the HTTP Upgrade request
wss.on('connection', (socket, request) => {
    // TODO put request.headers.cookie into a map of cookies then look for the token
    const token = request.headers.cookie ? request.headers.cookie.split(';')[0].split('=')[1] : undefined;

    // this method checks the token and does rooms.join('authenticated', socket);
    checkToken(token, socket);

    // put everyone in the public room, authed or not
    rooms.join('public', socket);

    socket.on('message', (msg) => {
        let message = JSON.parse(msg);
        // if they specifically send an 'auth' message, check the token and put
        // them in the authenticated room if the token is valid
        if(message.action && message.action === 'auth') {
            checkToken(message.token, socket);
        }
    });

    socket.on('close', (code, reason) => {
        rooms.leaveAll(socket);
    });
});
morfair commented 3 years ago

@elliottross23 Only you should remember that if you are using the GET method, you are limited to a maximum of 2,048 characters, minus the number of characters in the actual path.