Sling Academy
Home/Node.js/Sequelize.js: How to Auto-Hash Passwords

Sequelize.js: How to Auto-Hash Passwords

Last updated: December 29, 2023

Introduction

In modern web development, handling user passwords with utmost security is crucial. Passwords should never be stored as plain text in databases. Instead, they should be hashed using a robust algorithm. Sequelize, a Node.js ORM for relational databases like PostgreSQL, MySQL, SQLite, and MSSQL, offers a simple yet powerful way to hash passwords before they are stored. This guide will cover how to automatically hash passwords in Sequelize using lifecycle hooks and the bcrypt library.

Setting Up Sequelize Model

First, you need to set up your Sequelize model. Here’s a simple User model with a password field:

const { Sequelize, Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  dialect: 'mysql',
  // other options
});
class User extends Model {}
User.init({
  username: DataTypes.STRING,
  password: DataTypes.STRING
}, { sequelize, modelName: 'user' });

Installing Bcrypt

Before proceeding, ensure that you have bcrypt installed:

npm install bcrypt

Now, you can require it in your file:

const bcrypt = require('bcrypt');

Auto-Hashing Passwords Using Hooks

To hash passwords automatically, you can use Sequelize’s ‘beforeCreate’ and ‘beforeUpdate’ hooks. These hooks are called before a model instance is created or updated, respectively.

User.beforeCreate((user, options) => {
  const salt = bcrypt.genSaltSync();
  user.password = bcrypt.hashSync(user.password, salt);
});
User.beforeUpdate((user, options) => {
  if (user.changed('password')) {
    const salt = bcrypt.genSaltSync();
    user.password = bcrypt.hashSync(user.password, salt);
  }
});

Handling Password Verification

To verify passwords during login:

User.prototype.validPassword = function(password) {
  return bcrypt.compareSync(password, this.password);
};

To use this method:

const isMatch = userInstance.validPassword('inputPassword');
if (isMatch) {
  // Passwords match
} else {
  // Password does not match
}

Advanced Usage

If you want to hash passwords asynchronously or incorporate more complex logic, you can use asynchronous hooks and bcrypt’s asynchronous functions.

User.beforeCreate(async (user, options) => {
  const salt = await bcrypt.genSalt();
  user.password = await bcrypt.hash(user.password, salt);
});

In the context of password verification for login, you could modify the validPassword method to be async as well:

User.prototype.validPassword = async function(password) {
  return await bcrypt.compare(password, this.password);
};

Conclusion

Auto-hashing passwords in Sequelize is a best practice that should be implemented in any application handling user credentials. This not only secures the passwords but also abstracts the complexity from developers. Following the steps outlined in this guide will ensure that your user’s passwords are handled securely. Always keep your dependencies updated and review your security strategies constantly to keep up with evolving threats.

Next Article: Sequelize Upsert: How to insert or update a record in one query

Previous Article: Sequelize.js: How to Validate Numbers and Text Length

Series: Sequelize.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates