# Coldbox Security Authentication

> Use this skill when implementing user authentication in ColdBox with CBAuth, creating user services with retrieveUserById/retrieveUserByUsername, hashing passwords with BCrypt, managing login/logout sessions, implementing remember me functionality, or setting up the CBAuth module configuration.

- Skill: `coldbox/coldbox-security-authentication` (Agent Skill)
- Install (CLI): `npx skillmds@latest add coldbox/coldbox-security-authentication`
- Raw SKILL.md: https://api.skillmd.com/api/skills/coldbox/coldbox-security-authentication/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: ColdBox (https://skillmd.com/u/coldbox)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/coldbox/coldbox-security-authentication

---


# Authentication Patterns in ColdBox

## Overview

CBAuth provides user authentication for ColdBox applications with session management, password hashing (BCrypt), remember me functionality, and user session storage.

## Language Mode Reference

Examples use **BoxLang (`.bx`)** syntax by default. Adapt for your target language:

| Concept | BoxLang (`.bx`) | CFML (`.cfc`) |
|---------|-----------------|---------------|
| Class declaration | `class [extends="..."] {` | `component [extends="..."] {` |
| DI annotation | `@inject` above `property name="svc";` | `property name="svc" inject="svc";` |
| View templates | `.bxm` suffix | `.cfm` / `.cfml` suffix |
| Tag prefix | `<bx:if>`, `<bx:output>`, `<bx:set>` | `<cfif>`, `<cfoutput>`, `<cfset>` |

> **CFML Compat Mode**: With BoxLang + CFML Compat module, `.bx` and `.cfc` files coexist freely. BoxLang-native classes use `class {}` (`.bx` files); CFML-compat classes use `component {}` (`.cfc` files).

## Installation

```bash
box install cbauth
box install bcrypt
```

## Configuration

```boxlang
// config/ColdBox.cfc
moduleSettings = {
    cbauth: {
        userServiceClass: "UserService@models",
        userModel: "User@models",
        rememberMe: {
            enabled: true,
            cookieName: "remember_me",
            days: 30
        }
    }
}
```

## User Service (Required by CBAuth)

```boxlang
/**
 * models/UserService.cfc
 * Must implement three CBAuth-required methods
 */
class singleton {

    property name="bcrypt" inject="@BCrypt"

    // Required: Retrieve user by ID
    function retrieveUserById( required id ) {
        return queryExecute(
            "SELECT * FROM users WHERE id = :id",
            { id: arguments.id }
        ).reduce( ( acc, row ) => row )
    }

    // Required: Retrieve user by username/email
    function retrieveUserByUsername( required username ) {
        return queryExecute(
            "SELECT * FROM users WHERE email = :email",
            { email: arguments.username }
        ).reduce( ( acc, row ) => row )
    }

    // Required: Validate credentials
    function isValidCredentials( required username, required password ) {
        try {
            var user = retrieveUserByUsername( arguments.username )
            return bcrypt.checkPassword( arguments.password, user.password )
        } catch ( any e ) {
            return false
        }
    }

    function create( required data ) {
        var hashedPwd = bcrypt.hashPassword( arguments.data.password )

        var qry = queryExecute(
            "INSERT INTO users (name, email, password) VALUES (:name, :email, :pwd)",
            {
                name:  arguments.data.name,
                email: arguments.data.email,
                pwd:   hashedPwd
            }
        )

        return retrieveUserById( qry.generatedKey )
    }
}
```

**CFML (`.cfc`):**

```cfml
/**
 * models/UserService.cfc
 * Must implement three CBAuth-required methods
 */
component {

    property name="bcrypt" inject="@BCrypt"

    // Required: Retrieve user by ID
    function retrieveUserById( required id ) {
        return queryExecute(
            "SELECT * FROM users WHERE id = :id",
            { id: arguments.id }
        ).reduce( ( acc, row ) => row )
    }

    // Required: Retrieve user by username/email
    function retrieveUserByUsername( required username ) {
        return queryExecute(
            "SELECT * FROM users WHERE email = :email",
            { email: arguments.username }
        ).reduce( ( acc, row ) => row )
    }

    // Required: Validate credentials
    function isValidCredentials( required username, required password ) {
        try {
            var user = retrieveUserByUsername( arguments.username )
            return bcrypt.checkPassword( arguments.password, user.password )
        } catch ( any e ) {
            return false
        }
    }

    function create( required data ) {
        var hashedPwd = bcrypt.hashPassword( arguments.data.password )

        var qry = queryExecute(
            "INSERT INTO users (name, email, password) VALUES (:name, :email, :pwd)",
            {
                name:  arguments.data.name,
                email: arguments.data.email,
                pwd:   hashedPwd
            }
        )

        return retrieveUserById( qry.generatedKey )
    }
}
```

## Login Handler

```boxlang
/**
 * handlers/Auth.cfc
 */
class extends="coldbox.system.EventHandler" {

    property name="auth" inject="AuthenticationService@cbauth"

    // GET /login
    function login( event, rc, prc ) {
        if ( auth.isLoggedIn() ) {
            relocate( "main.index" )
        }
        event.setView( "auth/login" )
    }

    // POST /login
    function doLogin( event, rc, prc ) {
        event.paramValue( "email",       "" )
        event.paramValue( "password",    "" )
        event.paramValue( "rememberMe",  false )

        try {
            auth.authenticate( rc.email, rc.password )

            if ( rc.rememberMe ) {
                auth.setRememberMe( 30 )
            }

            flash.put( "success", "Welcome back!" )
            relocate( "main.index" )

        } catch ( InvalidCredentials e ) {
            flash.put( "error", "Invalid email or password" )
            relocate( "auth.login" )
        }
    }

    // POST /logout
    function doLogout( event, rc, prc ) {
        auth.logout()
        flash.put( "info", "You have been logged out" )
        relocate( "auth.login" )
    }

    // GET /register
    function register( event, rc, prc ) {
        event.setView( "auth/register" )
    }

    // POST /register
    function doRegister( event, rc, prc ) {
        event.paramValue( "name",     "" )
        event.paramValue( "email",    "" )
        event.paramValue( "password", "" )

        userService.create( {
            name:     rc.name,
            email:    rc.email,
            password: rc.password
        } )

        // Auto-login after registration
        auth.authenticate( rc.email, rc.password )

        relocate( "main.index" )
    }
}
```

**CFML (`.cfc`):**

```cfml
/**
 * handlers/Auth.cfc
 */
component extends="coldbox.system.EventHandler" {

    property name="auth" inject="AuthenticationService@cbauth"

    // GET /login
    function login( event, rc, prc ) {
        if ( auth.isLoggedIn() ) {
            relocate( "main.index" )
        }
        event.setView( "auth/login" )
    }

    // POST /login
    function doLogin( event, rc, prc ) {
        event.paramValue( "email",       "" )
        event.paramValue( "password",    "" )
        event.paramValue( "rememberMe",  false )

        try {
            auth.authenticate( rc.email, rc.password )

            if ( rc.rememberMe ) {
                auth.setRememberMe( 30 )
            }

            flash.put( "success", "Welcome back!" )
            relocate( "main.index" )

        } catch ( InvalidCredentials e ) {
            flash.put( "error", "Invalid email or password" )
            relocate( "auth.login" )
        }
    }

    // POST /logout
    function doLogout( event, rc, prc ) {
        auth.logout()
        flash.put( "info", "You have been logged out" )
        relocate( "auth.login" )
    }

    // GET /register
    function register( event, rc, prc ) {
        event.setView( "auth/register" )
    }

    // POST /register
    function doRegister( event, rc, prc ) {
        event.paramValue( "name",     "" )
        event.paramValue( "email",    "" )
        event.paramValue( "password", "" )

        userService.create( {
            name:     rc.name,
            email:    rc.email,
            password: rc.password
        } )

        // Auto-login after registration
        auth.authenticate( rc.email, rc.password )

        relocate( "main.index" )
    }
}
```

## Protecting Routes (CBSecurity)

```boxlang
// config/ColdBox.cfc — protect routes requiring auth
moduleSettings = {
    cbsecurity: {
        firewall: {
            enabled: true,
            defaultAuthenticationAction: "redirect",
            invalidAuthenticationEvent: "auth.login"
        },
        rules: [
            // Public routes
            {
                secureList: "auth\\..*,main\\.index",
                whiteList: true,
                match: "event"
            },
            // Protected dashboard
            {
                secureList: "^dashboard\\.",
                match: "event",
                action: "redirect",
                redirect: "/login"
            }
        ]
    }
}
```

## Accessing the Logged-In User

```boxlang
class extends="coldbox.system.EventHandler" {

    property name="auth" inject="AuthenticationService@cbauth"

    function dashboard( event, rc, prc ) {
        // Check authentication
        if ( !auth.isLoggedIn() ) {
            relocate( "auth.login" )
        }

        // Get current user
        prc.user = auth.getUser()

        event.setView( "dashboard/index" )
    }
}
```

**CFML (`.cfc`):**

```cfml
component extends="coldbox.system.EventHandler" {

    property name="auth" inject="AuthenticationService@cbauth"

    function dashboard( event, rc, prc ) {
        // Check authentication
        if ( !auth.isLoggedIn() ) {
            relocate( "auth.login" )
        }

        // Get current user
        prc.user = auth.getUser()

        event.setView( "dashboard/index" )
    }
}
```

## Remember Me View Integration

```html
<!-- views/auth/login.cfm -->
<form action="#event.buildLink( 'auth.doLogin' )#" method="post">
    #csrf()#
    <input type="email" name="email" required />
    <input type="password" name="password" required />
    <label>
        <input type="checkbox" name="rememberMe" value="true" /> Remember me
    </label>
    <button type="submit">Login</button>
</form>
```

## CBAuth Methods Quick Reference

| Method | Description |
|--------|-------------|
| `auth.authenticate( username, password )` | Validate and log in user |
| `auth.isLoggedIn()` | Check if user is authenticated |
| `auth.getUser()` | Get the current authenticated user |
| `auth.logout()` | Log out current user |
| `auth.setRememberMe( days )` | Enable remember me cookie |
| `auth.getUserId()` | Get authenticated user's ID |

