Skip to content

User Registration

User registration is the process of creating a new user account in the system. The server receives the userโ€™s information, validates it, hashes the password, and stores the account in the database.

The key steps are:

  1. User fills out a registration form.
  2. Server validates the input data.
  3. Server hashes the password.
  4. Server stores the user in the database.
  5. User is redirected to the login page.

A typical registration form collects the following fields:

  • First Name and Last Name for personalization.
  • Username as an alternative login identifier.
  • Email as the primary identifier and for communication.
  • Password as the authentication credential.
  • Confirm Password to prevent typos.

Both email and username are collected so users can log in with either. The email serves for communication, while the username provides privacy by not exposing the email publicly.


Server-side validation is critical. Never trust client-side validation alone, as users can bypass JavaScript validation easily.

ValidationPurpose
Required fieldsEnsure data completeness
Email formatMust be valid email syntax
Email uniquenessPrevent duplicate accounts
Username uniquenessPrevent duplicate identifiers
Password lengthMinimum 8 characters for security
Password complexityRequire numbers/special characters
Password matchConfirm password typed correctly

Storing passwords in plain text is one of the most dangerous mistakes in web development. If the database is compromised, an attacker immediately sees every password in the system. Users who reuse passwords across services are then compromised everywhere.

Hashing is a one-way mathematical function that converts passwords into unreadable fixed-length strings. PHP provides two functions for this:

  • password_hash($password, PASSWORD_DEFAULT) converts a plain-text password into a hash for storage.
  • password_verify($plainPassword, $storedHash) checks whether a plain-text password matches a stored hash.

Key properties of hashing:

  • It is one-way: you cannot reverse a hash back to the original password.
  • Each hash is unique because PHP automatically adds a random salt.
  • It is intentionally slow to prevent brute-force attacks.
  • PHP upgrades to stronger algorithms automatically when you use PASSWORD_DEFAULT.

For example, the password "myPassword123" might produce a hash like $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi. The original password is never stored anywhere.


โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ User fills โ”‚
โ”‚ registration โ”‚
โ”‚ form โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Validate input โ”‚
โ”‚ - Required? โ”‚
โ”‚ - Valid email? โ”‚
โ”‚ - Unique? โ”‚
โ”‚ - Strong pwd? โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
โ”‚ โ”‚
โ–ผ โ–ผ
Valid Invalid
โ”‚ โ”‚
โ”‚ โ””โ”€โ”€> Show errors,
โ”‚ redirect back to registration form
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Hash password โ”‚
โ”‚ using bcrypt โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ INSERT into โ”‚
โ”‚ users table โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Redirect to โ”‚
โ”‚ /login โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The users table needs to store identity, authentication, and authorization data:

  • id (INT, Primary Key, Auto-Increment)
  • first_name, last_name (VARCHAR) for the userโ€™s name
  • username (VARCHAR, UNIQUE) for login
  • email (VARCHAR, UNIQUE) for login and communication
  • password_hash (VARCHAR 255) for the bcrypt hash
  • role (ENUM: โ€˜adminโ€™, โ€˜customerโ€™) for authorization
  • created_at, updated_at (DATETIME) for audit timestamps

The UNIQUE constraints on email and username prevent duplicate accounts. The password_hash column uses VARCHAR(255) because bcrypt produces hashes of about 60 characters, but 255 provides room for future algorithm upgrades.