Blog

Eric Peterson

August 16, 2019

Spread the word


Share your thoughts

You know what's tedious? Authentication. Every project I start needs some sort of authentication system. And every project I start basically from scratch.

I noticed this pattern a while ago and created some libraries to help. You may have used them before.

cbauth is a library that handles creating user sessions for you app while giving enough customization to use different authentication methods and session storages.

auth.authenticate( username, password );
auth.isLoggedIn();
auth.getUser();
auth.logout();

While cbauth manages user sessions, it doesn't protect handlers or actions from being accessed by logged out or unauthorized users. cbguard was created for this purpose providing a way to restrict access to certain handlers and/or actions using annotations.

component secured {

    function index( event, rc, prc ) { /* ... */ }

    function create( event, rc, prc ) secured="create_posts" { /* ... */ }

}

Part of the reason for this customization is that there is not just one way to handle user persistance. Not only is there not just one way, there is not a default way. This can be considered a strength or a weakness of the community, but instead of debating that, I've decided to finally fill that gap using some hand picked libraries.

For data persistance I chose Quick, a ColdBox ORM engine. Unlike Hibernate, Quick is written in CFML and so can be contributed to and by any CFML developer. It also avoids the obscure Hibernate error messages that CF ORM is known for. For example, here's our User component:

component extends="quick.models.BaseEntity" {

    property name="bcrypt" inject="@BCrypt" persistent="false";

    property name="id";
    property name="email";
    property name="password";

    public User function setPassword( required string password ) {
        return assignAttribute(
            "password",
            bcrypt.hashPassword( arguments.password )
        );
    }

    public boolean function hasPermission( required string permission ) {
        return true;
    }

    public boolean function isValidCredentials(
        required string email,
        required string password
    ) {
        var user = newEntity().where( "email", arguments.email ).first();
        if ( ! user.isLoaded() ) {
            return false;
        }
        return bcrypt.checkPassword( arguments.password, user.getPassword() );
    }

    public User function retrieveUserByUsername( required string email ) {
        return newEntity()
            .where( "email", arguments.email )
            .firstOrFail();
    }

    public User function retrieveUserById( required numeric id ) {
        return newEntity().findOrFail( arguments.id );
    }

    public struct function getMemento() {
        return {
            "email": variables.getEmail()
        }
    }

}

This User entity is used both to represent a User in our system as well as handle intergrating with cbauth and cbguard. Properties are mapped to columns. The plural component name is used as the table name. A fluent syntax based off of qb is used to create, retrieve, update, and delete records. I think you'll find it a joy to work with.

There are plenty of other modules added and configured:

  • cbValidation is used to make sure all the data used is valid.
  • bCrypt is used to hash passwords in the database.
  • commandbox-dotenv and commandbox-cfconfig are installed to start up our servers with the correct settings.
  • A users table migration is provided and commandbox-migrations is installed to apply it.
  • Form submissions are automatically checked for a CSRF token with verify-csrf-interceptor.
  • Even niceties like redirectBack and a custom UniqueInDatabase validator are provided to completely show how I would start off an authentication system using ColdBox and Quick.
  • And last, but not least, code formatting is handled automatically using commandbox-cfformat.

The best part, this is just the starting point! Is this good enough for you? Get going on the rest of your app. Need some more information for your users? Add a migration, modify the form, and update the entity component. Have a different authentication system like LDAP or OAuth? Update your authenticationService with cbauth in your config/ColdBox.cfc file.

You can get started today using this new skeleton in your coldbox create app command:

coldbox create app skeleton=cbtemplate-quick-with-auth

Edit your .env file and server start!

I hope this gets you up and going faster than ever creating your awesome ColdBox applications!

Add Your Comment

Recent Entries

12 Days of BoxLang - Day 4: TestBox

12 Days of BoxLang - Day 4: TestBox

Today we’re celebrating one of the most exciting new additions to the BoxLang ecosystem:

the TestBox BoxLang CLI Runner — a fast, native way to run your TestBox tests directly through the BoxLang Runtime. ⚡

No server required. No CommandBox needed. Just pure, ultra-fast BoxLang-powered testing from the command lineon Windows, Mac, and Linux.

If you’re building modern applications with BoxLang — web apps, CLIs, serverless functions, Android apps, or OS-level utilities — this new feature gives you a unified, flexible testing workflow you can run anywhere.

Victor Campos
Victor Campos
December 13, 2025
12 days of BoxLang - Day 3: SocketBox!

12 days of BoxLang - Day 3: SocketBox!

As BoxLang continues evolving into a modern, high-performance, JVM-based runtime, real-time communication becomes essential for the applications we all want to build: dashboards, collaboration tools, notifications, live feeds, multiplayer features, and more.

That’s where SocketBox steps in — the WebSocket upgrade listener built to work seamlessly with CommandBox and the BoxLang MiniServer. ⚡

Today, for Day 3, we’re highlighting how SocketBox supercharges BoxLang development by giving you fast, flexible, and framework-agnostic WebSocket capabilities.

Maria Jose Herrera
Maria Jose Herrera
December 12, 2025
12 Days of BoxLang - Day 2: CommandBox

12 Days of BoxLang - Day 2: CommandBox

BoxLang + CommandBox: The Enterprise Engine Behind Your Deployments

For Day 2 of our 12 Days of Christmas series, we’re diving into one of the most powerful parts of the BoxLang ecosystem: CommandBox the defacto enterprise servlet deployment platform for BoxLang.

If BoxLang is the language powering your applications, CommandBox is the engine room behind it all. ⚙️

Victor Campos
Victor Campos
December 11, 2025