H
H
hbrmdc2015-12-20 21:11:55
User identification
hbrmdc, 2015-12-20 21:11:55

How to correctly implement authentication in SPA on Socket.io?

Socket.io, Express, PostgreSQL.
The web application is available for viewing by both authorized users and guests. All communication with the server is exclusively through wss. After reviewing several articles about the implementation of authentication, I came to the following.
The guest enters the site, a handshake occurs, a connection to the server is established. Since this is not a restful http connection, but ws, the sid (session id) is not needed for unauthorized users. While there is no sida, only a limited number of functions (queries to the database) are available to the guest.
The guest enters the username and password in the authorization form, and presses "login". The login-password pair is sent via https. Since there is an SSL certificate, the password is sent without encryption. On the server, the password is encrypted with SHA256, after which the database is searched for the login-encrypted_password pair corresponding to the entered data. If a match is found, then a sid (guid) and a one-time key for ws (let's call it wskey) are generated. Both keys are added to the 'users' table of the database. Both keys are sent to the client. On the client, the sid is stored in a cookie labeled HttpOnly, and the wskey is immediately used to send over ws. Server-side socket.io searches the database for a user with this wskey. If found, then socket.io receives sid and somehow binds it to the current connection so that it is further attached to all client requests to the server. (1) How to do it? Once the sid is stored in socket.io, the wskey is removed from the database.
That is, further the client makes requests without sid or something like that, but socket.io "remembers" it and attaches sid to each request, after which it sends it for further processing.
The user did what he wanted and closed the browser.
The user opened the browser again and went to the site.
An HTTPS request is made containing the sid from the cookie. The server received a sid, found a row with this sid in the database in the users table, and followed the same scheme - create a wskey, send it to the client, and so on.
2. If there are any mistakes in the written - please criticize)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey, 2015-12-20
@hbrmdc

the password is sent without encryption

without SSL ping, you can also encrypt the password, but not everyone needs it.
it is not encrypted but hashed, and it is better to hash in BCRYPT (or even SCRYPT but I would still wait a couple of years)
Mmm... the chances are certainly small... I would even say meager, but in this way we become vulnerable to timing attacks. At the moment, an adequate algorithm is a search by login (identity, login or email or whatever you use there to identify the user) and then check the password hashes character by character:
var matches = true;
for(var i = 0; i < 1024; i++) {
    if (str1[i] !== str2[i]) matches = false;
}

why so bad? because read about attack timing. There is even a documented case of exploiting timing attacks to match hash collisions over the Internet (that is, with delays of the order of 10 or more milliseconds)! True, for this you need to make a couple of million requests, well, carry it.
Another good idea is that the socker.io server asks the authorization server for the correct wskey or not, but this is if you run out of scaling.
In general, everything is correct. And if you don’t bother with such things as separation of responsibility (they say you have a separate socket-io server and a separate application), then you can also use JWT. Then we don’t need to store anything anywhere at all, and you can check the validity by the signature of the token. Yes, and the implementation is ready.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question