Skip to content
Noel A. Dacara edited this page Mar 22, 2021 · 1 revision

User Registration and Authentication

The registration and authentication routines will be common for both protocols, and will be performed once a WebSocket connection has been established.

Registration

This section will only describe the common data needed for user registration. Each protocol will require a different set of data.

To register a user, the client needs to send at least a username and a hashedPassword. The value for the hashedPassword is simply a SHA256 HMAC of the username and the plaintext password as the key. An example on how to do this in JavaScript is displayed below (uses the hashing library from https://github.com/Caligatio/jsSHA):

var shaObj = new jsSHA("SHA-256", "TEXT");
shaObj.setHMACKey("somePassword", "TEXT");
shaObj.update("johndoe");
//hashedPassword will contain the value 8437ae0231129d7038809d7aa68e89430b73e245b99b9cc662cbc0bd9cc6f6da
var hashedPassword = shaObj.getHMAC("HEX");

The data will then be sent to the server via the WebSocket connection as a JSON object formatted as follows:

{
    "command": "register",
    "username": "johndoe",
    "hashedPassword": "8437ae0231129d7038809d7aa68e89430b73e245b99b9cc662cbc0bd9cc6f6da"
    ...
}

Once the server receives this message, it should do some processing before proceeding to save the information to the database. Saving the password information will require yet another SHA256 HMAC of the existing hashedPassword with an internally agreed upon key (for the purposes of this document, we'll use superSecretKey). An example to do this in PHP:

//hashedPassword = 8437ae0231129d7038809d7aa68e89430b73e245b99b9cc662cbc0bd9cc6f6da
$hmacForSaving = hash_hmac('sha256', $hashedPassword, 'superSecretKey');
//hmacForSaving will contain the value 92d55f54ca872dc20c2f882b22e152f9c82ff62c66e1b9461e9f80011b3255c6

The value of hmacForSaving will be the one valid for saving into the database. An example document in MongoDB will look like the following:

{
    "username": "johndoe",
    "password": "92d55f54ca872dc20c2f882b22e152f9c82ff62c66e1b9461e9f80011b3255c6",
    ...
}

With this registration flow, the user password (somePassword in the examples) will only ever exist in memory as plaintext while entered in the registration form.

Authentication

This section will only describe the common data needed for user registration. Each protocol will require a different set of data.

To begin the authentication process, the client needs to send a request for a limited-time random salt. This is done by sending a command to the server in JSON format:

{
    "command": "loginSalt",
    "username": "johndoe"
}

Upon receiving this message, the server will check if the user johndoe exists in the database, then generate a random string 64 characters in length. For the simplicity in these examples, let's assume that the randomly generated string is cbb4a64006378ec261840d39ab6cc76048f3dad16e19b7db508fb11ba4594c51. This will be saved by the server for later reference 5 minutes max. This will then be sent back to the client as a message in the following JSON format:

{
    "command": "loginSalt",
    "username": "johndoe",
    "validity": 300,
    "salt": "cbb4a64006378ec261840d39ab6cc76048f3dad16e19b7db508fb11ba4594c51"
}

Upon receiving this message, the client will have 300 seconds to actually perform a login. This is done by retrieving the saved password for the specified user (johndoe in our example), or performing the series of hashes described in the user registration section above to obtain the hash 92d55f54ca872dc20c2f882b22e152f9c82ff62c66e1b9461e9f80011b3255c6 from the plaintext password somePassword as retrieved from the login form. Using the salt as the key, we again use a SHA256 HMAC routine to generate a loginChallenge string. This is done in JavaScript as follows:

var shaObj = new jsSHA("SHA-256", "TEXT");
//this is the salt we received from the server
shaObj.setHMACKey("cbb4a64006378ec261840d39ab6cc76048f3dad16e19b7db508fb11ba4594c51", "TEXT");
//this is the saved password, or the resulting HMAC of username + plaintext password + superSecretKey
shaObj.update("92d55f54ca872dc20c2f882b22e152f9c82ff62c66e1b9461e9f80011b3255c6");
//loginChallenge will contain the value 02b78364fee0f76cdfb64c17b6a919b2940198742cb3f989af9271a81e9471c8
var loginChallenge = shaObj.getHMAC("HEX");

The resulting hash will now be sent to the server as a login request. The message format is as follows:

{
    "command": "login",
    "username": "johndoe",
    "challenge": "02b78364fee0f76cdfb64c17b6a919b2940198742cb3f989af9271a81e9471c8"
}

When the server receives this command, it will check if the user johndoe has a valid salt. It will then retrieve the saved password for the user, then apply the HMAC algorithm described above. The resulting hash should be exactly the same as the challenge string sent in by the client.

Session Management

Upon successful login, the backend will return a sessionID that needs to be used in most of the other API endpoints. This sessionID will have a finite lifetime, and will need to be refreshed before it expires. Once a sessionID is expired, authentication needs to be performed again to obtain a valid sessionID.

Verification Code System for Registration

Create Verification Code

This command is used to create a new verificationCode and be sent to the email address provided. Provided verificationCode will be used to verify the email address. Verification codes are valid only for a limited amount of time. Users can request only limited amount of verification codes per day. Command: emailVerification

Client Request Parameters:

email (string) - A string specifying the user's email address
username (string) - A string specifying the user's username

Example JSON message:

{
    "command": "emailVerification",
    "email": "[email protected]",
    "username": "johndoe"
}

Server Response Parameters:

success (boolean) - Specifies if the operation was successful

Example JSON message:

{
    "command": "emailVerification",
    "success": true,
}

API Messages

Described below are the API messages relevant to this section.

User Registration

This command is sent by the client to register a user to the system. Command: register

Client Request Parameters:

username (string) - A string uniquely identifying the user within the Sidekick network. Only accepts Latin Alphabet characters(A-z, a-z, 0-9).
displayName (string) - A string identifying the user's public alias/name. Doesn't need to be unique to the network. Can accept any unicode character.
password (string) - A hexadecimal string derived from hashing the user's plaintext password against the username
password2 (string) - A hexadecimal string derived from hashing the user's plaintext password against the email address
password3 (string) - A hexadecimal string derived from hashing the user's plaintext password against the display name
email (string) - A string specifying the email address used for recovering the account
verificationCode (string) - A string specifying the verification code received via the provided email address

Example JSON message:

{
    "command": "register",
    "username": "johndoe",
    "displayName": "Bigjohndoe",
    "password": "8437ae0231129d7038809d7aa68e89430b73e245b99b9cc662cbc0bd9cc6f6da",
    "password2": "55212a9a47b566ca3aa4ab24a00a0d1579d47cc9367ed15c1be61aa05c3467c3",
    "password3": "cdd3485891de29fb1f242676bdb6d8b515a619b5ecfceae651bd01340b00a778",
    "email": "[email protected]",
    "verificationCode": "123456"
}

Server Response Parameters:

username (string) - A string uniquely identifying the user
success (bool) - A boolean value specifying if the registration request was successful

Example JSON message:

{
    "command": "register",
    "username": "johndoe",
    "success": true
}

Check Username Availability

This command is sent by the client to check if a username is still available for registration. Command: checkUsername

Client Request Parameters:

username (string) - A string uniquely identifying the user

Example JSON message:

{
    "command": "checkUsername",
    "username": "johndoe"
}

Server Response Parameters:

username (string) - A string uniquely identifying the user
available (bool) - A boolean value specifying if the username is available

Example JSON message:

{
    "command": "checkUsername",
    "username": "johndoe",
    "available": true
}

Check Email Availability

This command is sent by the client to check if an email address is not yet registered in the system. Command: checkEmail

Client Request Parameters:

email (string) - A string specifying the user's email address

Example JSON message:

{
    "command": "checkEmail",
    "email": "[email protected]"
}

Server Response Parameters:

email (string) - A string specifying the user's email address
available (bool) - A boolean value specifying if the email is available

Example JSON message:

{
    "command": "checkEmail",
    "email": "[email protected]",
    "available": true
}

Request Login Salt

This command is sent by the client to initiate a login attempt. Command: loginSalt

Client Request Parameters:

username (string) - A string uniquely identifying the user

Example JSON message:

{
    "command": "loginSalt",
    "username": "johndoe"
}

Server Response Parameters:

username (string) - A string uniquely identifying the user
validity (number) - A number specifying the number of seconds the salt is valid
salt (string) - A string specifying the randomly generated salt.

Example JSON message:

{
    "command": "loginSalt",
    "username": "johndoe",
    "validity": 300,
    "salt": "cbb4a64006378ec261840d39ab6cc76048f3dad16e19b7db508fb11ba4594c51"
}

Perform Login

This command is sent by the client to perform a login attempt. Command: login

Client Request Parameters:

usernameOrEmail (string) - A string uniquely identifying the user
challenge (string) - A string containing the hash resulting from the salt and the hashed password

Example JSON message:

{
    "command": "login",
    "usernameOrEmail": "johndoe",
    "challenge": "02b78364fee0f76cdfb64c17b6a919b2940198742cb3f989af9271a81e9471c8"
}

Server Response Parameters:

username (string) - A string uniquely identifying the user
success (bool) - A boolean value indicating the success of the login attempt
sessionID (string) - A string specifying the session ID to use for authenticated requests
userID (string) - A string specifying the user ID associated with the useraccount
validity (number) - A number specifying the number of seconds the session ID is valid

Example JSON message for a successful login:

{
    "command": "login",
    "username": "johndoe",
    "success": true,
    "sessionID": "4a339896dfe936f2372d95bf2046871e56809a0b3ccae9d7f187418039971671",
    "userID": "buifu0812ehudasudg790382rh",
    "validity": 300
}

Example JSON message for a failed login:

{
    "command": "login",
    "username": "johndoe",
    "success": false,
    "sessionID": null,
    "validity": 0
}