There are 3 basic rules for keeping user credentials secure:
Lucky for us, the pgcrypto module in PostgreSQL makes it very easy to follow these rules. Let us take a look at an example.
First, we need to enable pgcrypto:
CREATE EXTENSION pgcrypto;
Then, we can create a table for storing user credentials:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
password TEXT NOT NULL
);
When creating a new user, we can use the crypt function to encrypt the password.
INSERT INTO users (email, password) VALUES (
'johndoe@mail.com',
crypt('johnspassword', gen_salt('bf'))
);
The crypt function accepts two arguments:
We should always use the gen_salt function, to let PostgreSQL generate a random salt for us. I prefer using the blowfish algorithm (bf) with gen_salt, but here is a list of the algorithms you can use:
To authenticate a user, we use crypt again, but this time we pass these arguments:
If the password matches, crypt will return the same value as the one we already have in the database.
SELECT id
FROM users
WHERE email = 'johndoe@mail.com'
AND password = crypt('johnspassword', password);
id
----
1
(1 row)
SELECT id
FROM users
WHERE email = 'johndoe@mail.com'
AND password = crypt('wrongpassword', password);
id
----
(0 rows)