Authentication

This guide introduces the AdonisJS authentication system. You will learn:

  • How guards and providers work together to authenticate users
  • Which guard to choose for your application type
  • How to install and configure the auth package
  • What the Initialize auth middleware does

Overview

AdonisJS provides a robust authentication system for logging in and authenticating users across different application types, whether you're building a server-rendered application, an API for a SPA, or a backend for mobile apps.

The authentication package is built around two core concepts:

  • Guards are end-to-end implementations of a specific authentication method. For example, the session guard authenticates users via cookies and sessions, while the access tokens guard authenticates requests using bearer tokens.
  • Providers handle user lookup and token verification from your database. You can use the built-in Lucid provider or implement your own for custom data sources.

The security primitives of AdonisJS are designed to protect against common vulnerabilities. Passwords and tokens are properly hashed, and the implementation guards against timing attacks and session fixation attacks.

What the auth package does not include

The auth package focuses specifically on authenticating HTTP requests. The following features are outside its scope:

  • User registration (forms, email verification, account activation)
  • Account management (password recovery, email updates)
  • Authorization and permissions (use Bouncer instead)
Tip

Looking for a complete authentication system? AdonisJS Kit provides full-stack components with ready-to-use flows for user registration, email verification, password recovery, profile management, and more.

Choosing an auth guard

AdonisJS ships with three built-in guards. Use the table below to determine which guard fits your application.

Application TypeRecommended GuardWhy
Server-rendered web appSessionCookies work naturally with browser requests
SPA on the same domainSessionShare cookies between api.example.com and example.com
SPA on a different domainAccess tokensCross-origin requests cannot share cookies
Mobile appAccess tokensNative apps cannot use cookie-based sessions
Third-party API accessAccess tokensClients need long-lived tokens they can store
Quick prototypingBasic authSimple to set up, no database tables required

Session guard

The session guard uses the @adonisjs/session package to track logged-in users. After a successful login, the user's identifier is stored in the session, and a session cookie is sent to the browser. Subsequent requests include this cookie, allowing the server to restore the user's authenticated state.

Sessions and cookies have been the standard for web authentication for decades. They work well when your client can accept and send cookies, which is the case for server-rendered applications and SPAs hosted on the same top-level domain as your API.

See also: Session guard documentation

Access tokens guard

Access tokens are cryptographically secure random strings issued to users after login. The client stores the token and includes it in the Authorization header of subsequent requests. AdonisJS uses opaque access tokens (not JWTs) that are stored as hashes in your database for verification.

Use access tokens when your client cannot work with cookies:

  • Native mobile applications
  • Desktop applications
  • Web applications on a different domain than your API
  • Third-party integrations that need programmatic API access

The client application is responsible for storing tokens securely. Access tokens provide unrestricted access to your application on behalf of a user, so leaking them creates security risks.

See also: Access tokens guard documentation

Basic auth guard

The basic auth guard implements the HTTP authentication framework. The client sends credentials as a base64-encoded string in the Authorization header with each request. If credentials are invalid, the browser displays a native login prompt.

Basic authentication is not recommended for production applications because credentials are sent with every request and the user experience is limited to the browser's built-in prompt. However, it can be useful during early development or for internal tools.

See also: Basic auth guard documentation

Choosing a user provider

User providers handle finding users and verifying tokens during authentication. Each guard type has specific requirements for its provider.

The session guard provider finds users by their ID (stored in the session). The access tokens guard provider additionally verifies tokens against hashed values in the database. AdonisJS ships with Lucid-based providers for all built-in guards, which use your Lucid models to query the database.

Installation

The auth package comes pre-configured with the web and api starter kits. To add it to an existing application, run one of the following commands based on your preferred guard:

# Session guard (recommended for web apps)
node ace add @adonisjs/auth --guard=session

# Access tokens guard (recommended for APIs)
node ace add @adonisjs/auth --guard=access_tokens

# Basic auth guard
node ace add @adonisjs/auth --guard=basic_auth
See steps performed by the add command
  1. Installs the @adonisjs/auth package using the detected package manager.

  2. Registers the following service provider inside the adonisrc.ts file.

    {
      providers: [
        // ...other providers
        () => import('@adonisjs/auth/auth_provider')
      ]
    }
  1. Creates and registers the following middleware inside the start/kernel.ts file.
    router.use([
      () => import('@adonisjs/auth/initialize_auth_middleware')
    ])
    router.named({
      auth: () => import('#middleware/auth_middleware'),
      // Only registered when using the session guard
      guest: () => import('#middleware/guest_middleware')
    })
  1. Creates the User model inside app/models.

  2. Creates database migrations for the users table.

  3. Creates additional migrations based on the selected guard (for example, auth_access_tokens for the access tokens guard).

The initialize auth middleware

During setup, the @adonisjs/auth/initialize_auth_middleware is added to your application's middleware stack. This middleware runs on every request and creates an instance of the Authenticator class, which it attaches to ctx.auth.

The initialize auth middleware does not authenticate requests or protect routes. Its only job is to set up the authenticator instance so it's available throughout the request lifecycle. To protect routes, use the auth middleware.

If your application uses Edge templates, the authenticator is also available as the auth variable:

@if(auth.isAuthenticated)
  <p>Hello {{ auth.user.email }}</p>
@end

Creating the users table

The add command creates a migration for the users table in database/migrations. You can modify this file to match your application's requirements before running the migration.

database/migrations/TIMESTAMP_create_users_table.ts
import { BaseSchema } from '@adonisjs/lucid/schema'

export default class extends BaseSchema {
  protected tableName = 'users'

  async up() {
    this.schema.createTable(this.tableName, (table) => {
      table.increments('id').notNullable()
      table.string('full_name').nullable()
      table.string('email', 254).notNullable().unique()
      table.string('password').notNullable()

      table.timestamp('created_at').notNullable()
      table.timestamp('updated_at').nullable()
    })
  }

  async down() {
    this.schema.dropTable(this.tableName)
  }
}

After modifying the migration, update the User model in app/models/user.ts to reflect any columns you've added, renamed, or removed.

Next steps

With the auth package installed, you're ready to implement authentication in your application: