Built-in Auth

Last updated: 04/17/2026 · Written by Agent0

Built-in Auth

StackCTL's core authentication covers registration, login, logout, and password reset. All of it works out of the box — no setup required beyond having your database running and your mail configured for password reset emails.


Registration

New users register at /register. The registration form collects first name, last name, email, and password. The controller validates the input, checks for duplicate emails, hashes the password using PHP's password_hash(), and creates the user record.

If email verification is enabled, the user is redirected to the login page with a message to check their inbox. If verification is off, they're logged in automatically and sent to /dashboard.

Disabling registration

For invite-only or internal apps, set allow_registration to false in config/auth.php. The registration page will redirect to /login and the form cannot be submitted.

'allow_registration' => false

Login

Users log in at /login with their email and password. The controller looks up the user, verifies the password with password_verify(), and checks any gates that are enabled — email verification and MFA — before creating the session.

The session stores a lightweight snapshot of the user:

$_SESSION['user'] = [
    'id'         => $user->id,
    'name'       => $user->first_name . ' ' . $user->last_name,
    'email'      => $user->email,
    'role'       => $user->role,
    'last_login' => $now,
];

The last_login timestamp is also written back to the users table on every successful login.

Use the auth() helper to read session values anywhere in the app:

auth('name')
auth('email')
auth('role')

For fresh database values use user() instead. See the Helpers Reference for full details.


Logout

Visiting /logout clears the session, destroys the session cookie, removes the Remember Me token from the database if one exists, and redirects to /.

Log out

Password Reset

The password reset flow requires mail to be configured in config/mail.php. The full flow:

  1. User visits /forgot and submits their email address
  2. If the email exists, a secure token is generated and stored in the password_resets table with a 1-hour expiry
  3. A reset link containing the token is emailed to the user
  4. The user clicks the link, lands on /reset?token=..., and submits a new password
  5. The password is hashed and saved, the token is deleted, and the user is redirected to login

Note: Whether or not the email exists in the database, the user always sees the same success message — this prevents email enumeration attacks where someone could probe which addresses are registered.


Password Security

Passwords are always hashed with PHP's password_hash($password, PASSWORD_DEFAULT) before being stored. This uses bcrypt by default and automatically upgrades to stronger algorithms as PHP evolves. Plain-text passwords are never stored anywhere in the system.


Protecting Routes

Use the built-in auth and guest middleware to protect routes. See the Auth & Middleware doc for the full reference.

// Require login
$router->get('/dashboard', 'DashboardController@index')
       ->middleware('auth');

// Redirect away if already logged in
$router->get('/login', 'AuthController@showLogin')
       ->middleware('guest');
Was this helpful?