Хеш пароля в Nest
Учётная запись для входа на сайт с материалами должна появиться сразу после старта, но хранить открытый пароль в колонке таблицы опасно даже для тестового окружения.
Наполнитель берёт заготовленный
текст пароля, прогоняет его через
scryptSync из встроенного
модуля node:crypto NodeJS
вместе с солью и сохраняет в базу
только строку хеша. В таблице
остаются логин и готовый хеш,
а исходный пароль в PostgreSQL
не попадает.
Покажем на примере постов:
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
login: string;
@Column()
passwordHash: string;
}
Сервис наполнения подготовит хеш и сохранит пользователя:
import { Injectable, OnModuleInit } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { randomBytes, scryptSync } from 'node:crypto';
import { Repository } from 'typeorm';
import { User } from '../user.entity.js';
@Injectable()
export class UserService implements OnModuleInit {
userRepository: Repository<User>;
constructor(
@InjectRepository(User) userRepository: Repository<User>,
) {
this.userRepository = userRepository;
}
async onModuleInit() {
const salt = randomBytes(16);
const hash = scryptSync('demo-pass', salt, 64);
const passwordHash = `${salt.toString('hex')}:${hash.toString('hex')}`;
await this.userRepository.save({
login: 'editor',
passwordHash,
});
}
findAll() {
return this.userRepository.find();
}
}
Контроллер откроет список без открытого пароля:
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service.js';
@Controller('users')
export class UserController {
userService: UserService;
constructor(userService: UserService) {
this.userService = userService;
}
@Get()
findAll() {
return this.userService.findAll();
}
}
Модуль темы регистрирует сущность и классы страницы:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../user.entity.js';
import { UserController } from './user.controller.js';
import { UserService } from './user.service.js';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [UserService],
})
export class UsersModule {}
Корень поднимает канал к базе и импортирует модуль темы:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module.js';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'site',
autoLoadEntities: true,
synchronize: true,
}),
UsersModule,
],
})
export class AppModule {}
При старте сохраните в
WorkerService работника
с логином и хешем пароля.
Список откройте в
WorkerController и соберите
WorkersModule с базой в корне.