The Hash module provides password hashing functionality with support for multiple hashing algorithms including Scrypt, Bcrypt, and Argon2.
Import
import { HashManager, Hash } from '@adonisjs/core/hash'
import { defineConfig, drivers } from '@adonisjs/core/hash'
import type { HashConfig, ScryptConfig, BcryptConfig, ArgonConfig } from '@adonisjs/core/types/hash'
Overview
The Hash module provides a unified API for password hashing using different algorithms. It includes a manager for handling multiple hash drivers and built-in drivers for Scrypt, Bcrypt, and Argon2.
Functions
defineConfig
Defines the hash service configuration with lazy loading support.
Configuration object containing default hasher and list of hashersOptional default hasher name (must exist in the list)
Record of hasher configurations or config providers
return
ConfigProvider<ResolvedConfig>
A configuration provider that lazily imports and resolves hash drivers
import { defineConfig, drivers } from '@adonisjs/core/hash'
const hashConfig = defineConfig({
default: 'scrypt',
list: {
scrypt: drivers.scrypt({
cost: 16384,
blockSize: 8,
parallelization: 1,
saltSize: 16,
keyLength: 64,
}),
bcrypt: drivers.bcrypt({
rounds: 10,
})
}
})
Drivers
The drivers object provides factory functions for creating hash driver configurations.
drivers.scrypt
Creates a Scrypt hash driver configuration.
Scrypt algorithm configuration optionsCPU/memory cost parameter (N)
Parallelization parameter (p)
Desired key length in bytes
scrypt: drivers.scrypt({
cost: 16384,
blockSize: 8,
parallelization: 1,
saltSize: 16,
keyLength: 64
})
drivers.bcrypt
Creates a Bcrypt hash driver configuration.
Bcrypt algorithm configuration optionsNumber of rounds for key derivation. Higher values = slower but more secure.
Bcrypt requires the bcrypt peer dependency to be installed: npm install bcrypt
bcrypt: drivers.bcrypt({
rounds: 12
})
drivers.argon2
Creates an Argon2 hash driver configuration.
Argon2 algorithm configuration optionsArgon2 variant: ‘i’, ‘d’, or ‘id’
Argon2 requires the argon2 peer dependency to be installed: npm install argon2
argon2: drivers.argon2({
variant: 'id',
memory: 65536,
time: 3,
parallelism: 4
})
Hash Service
The hash service is available via dependency injection and provides methods for hashing and verifying passwords.
Methods
make
Hashes a plain text password.
The plain text password to hash
A promise that resolves to the hashed password string
import hash from '@adonisjs/core/services/hash'
const hashedPassword = await hash.make('user-password')
// Returns: $scrypt$n=16384,r=8,p=1$...
verify
Verifies a plain text password against a hashed value.
The hashed password to verify against
The plain text password to verify
A promise that resolves to true if the password matches, false otherwise
import hash from '@adonisjs/core/services/hash'
const isValid = await hash.verify(hashedPassword, 'user-password')
if (isValid) {
console.log('Password is correct')
}
needsReHash
Checks if a hashed value needs to be rehashed (e.g., if the algorithm parameters have changed).
The hashed password to check
Returns true if the hash needs to be regenerated
import hash from '@adonisjs/core/services/hash'
if (hash.needsReHash(user.password)) {
user.password = await hash.make(plainPassword)
await user.save()
}
use
Returns a specific hash driver instance.
Optional driver name. If omitted, returns the default driver.
import hash from '@adonisjs/core/services/hash'
// Use default driver
const defaultHasher = hash.use()
// Use specific driver
const bcryptHasher = hash.use('bcrypt')
const hashed = await bcryptHasher.make('password')
Types
HashConfig
Configuration type for the hash service.
type HashConfig = {
default?: string
list: Record<string, ManagerDriverFactory | ConfigProvider<ManagerDriverFactory>>
}
ScryptConfig
Configuration options for the Scrypt driver.
type ScryptConfig = {
cost?: number
blockSize?: number
parallelization?: number
saltSize?: number
keyLength?: number
}
BcryptConfig
Configuration options for the Bcrypt driver.
type BcryptConfig = {
rounds?: number
}
ArgonConfig
Configuration options for the Argon2 driver.
type ArgonConfig = {
variant?: 'i' | 'd' | 'id'
memory?: number
time?: number
parallelism?: number
}
Example Usage
Configuration
// config/hash.ts
import { defineConfig, drivers } from '@adonisjs/core/hash'
import env from '@adonisjs/core/services/env'
export default defineConfig({
default: env.get('HASH_DRIVER', 'scrypt'),
list: {
scrypt: drivers.scrypt({
cost: 16384,
blockSize: 8,
parallelization: 1,
saltSize: 16,
keyLength: 64
}),
bcrypt: drivers.bcrypt({
rounds: 10
}),
argon2: drivers.argon2({
variant: 'id',
memory: 65536,
time: 3,
parallelism: 4
})
}
})
User Authentication
import hash from '@adonisjs/core/services/hash'
import User from '#models/user'
class AuthController {
async register({ request, response }: HttpContext) {
const data = request.only(['email', 'password'])
// Hash the password
const hashedPassword = await hash.make(data.password)
const user = await User.create({
email: data.email,
password: hashedPassword
})
return response.json(user)
}
async login({ request, response }: HttpContext) {
const { email, password } = request.only(['email', 'password'])
const user = await User.findByOrFail('email', email)
// Verify the password
const isValid = await hash.verify(user.password, password)
if (!isValid) {
return response.unauthorized({ message: 'Invalid credentials' })
}
// Check if password needs rehashing
if (hash.needsReHash(user.password)) {
user.password = await hash.make(password)
await user.save()
}
// Generate token and return
const token = await generateAuthToken(user)
return response.json({ token })
}
}
Using Different Drivers
import hash from '@adonisjs/core/services/hash'
// Use default driver (from config)
const hashed1 = await hash.make('password')
// Use specific driver
const bcryptHasher = hash.use('bcrypt')
const hashed2 = await bcryptHasher.make('password')
const argonHasher = hash.use('argon2')
const hashed3 = await argonHasher.make('password')
// Verify works with any driver automatically
const isValid = await hash.verify(hashed2, 'password') // true
Notes
- Import happens when you first use the hash module
- Driver construction happens when you first use a specific driver
- Scrypt is the recommended default driver as it doesn’t require additional dependencies
- Bcrypt and Argon2 require peer dependencies to be installed
- Always verify passwords using the
verify method, never compare hashes directly
- Use
needsReHash to upgrade hashes when configuration changes
- Higher cost parameters = slower hashing but better security