Introducción
Hola y bienvenid@ a esta nueva serie de blogs en la que veremos como construir un sistema completo de autenticación utilizando NestJS.
NestJS es un framework para Node.js en y en el que se utiliza typescript para escribir su código. Una de las mejores cualidades que tiene este framework es que utiliza la inyección de dependencias lo cual nos permite tener un código bien estructurado y fácil de escalar.
Si entras en la página de la documentación del framework puedes leer más sobre todo lo que se puede hacer con este framework.
Para seguir esta serie es necesario que sepas como funciona javascript y typescript y en caso de que no eres familiar con estos dos lenguajes puedes encontrar bastante contenido sobre ellos en youtube.
Antes de empezar te recomiendo suscribirte a nuestro newsletter para recibir un correo cada vez que publicamos un blog y para recibir descuentos exclusivos en nuestros futuros cursos.
Este blog es un resumen de los videos de nuestro canal de youtube. Si prefieres tener todas las detalles o prefieres ver un video que leer un blog puedes encontrar la serie aquí.
Puedes encontrar todo el código de esta serie en github.
Requisitos
Antes de empezar vamos a asegurarnos que tenemos todos los requisitos necesarios:
- Node.js
- Yarn
- Opcionalmente Docker
Dependencias y configuración de MySQL
Ahora tenemos que instalar el cli de NestJS y creamos un proyecto nuevo
yarn global add @nestjs/cli
nest new
Ahora vamos a instalar las dependencias que necesitamos para nuestro proyecto.
yarn add @nestjs/typeorm typeorm mysql2
Lo siguiente que tenemos que hacer es configurar la conexión de orm a mysql. Para hacerlo añadimos el modulo typeorm a los imports dentro del fichero app.module.ts
Entonces nuestro fichero de app.module.ts queda así:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 5000,
username: 'root',
password: 'codenip',
database: 'database',
autoLoadEntities: true,
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Ten cuidado de no llevar tu aplicación a la producción con la opción de synchronize igual a true ya que esto puede causar perdida de datos.
Lo siguiente que vamos a hacer es lanzar un contenedor de mysql.
docker run --name mysql-nestjs-auth -p 5000:3306 -e MYSQL_ROOT_PASSWORD=codenip -e MYSQL_DATABASE=database -d mysql:8.0.26
Y después lanzamos nuestro proyecto en modo desarrollo.
yarn start:dev
Librerías para seguridad y encriptación
Ahora vamos a instalar todas las dependencias necesarias para el tema de autenticación.
Para esta serie vamos a utilizar passport y JWT.
yarn add @nestjs/jwt @nestjs/passport @types/passport-jwt passport passport-jwt
Y lo siguiente que vamos a instalar es una librería para encriptar las contraseñas. Es importante que nunca guardes las contraseñas de los usuarios en texto plano o que las encriptes con algoritmos débiles como sha1 o md5.
yarn add bcrypt
Librerías para validación
Ahora vamos a instalar las ultimas dependencias que necesitamos para esta serie.
NestJS ya nos provee dos librerías para validar nuestros requests.
yarn add class-validator class-transformer
Ya estamos listos para desarrollar nuestra aplicación.
Creando AuthModule
Es la hora de empezar de desarrollar la lógica para nuestro sistema de autenticación.
Lo primero que vamos a hacer es crear un AuthModule para en el que vamos a tener toda la lógica de autenticación de nuestros usuarios.
Para ellos vamos a utilizar el command line de nest y vamos creando el modulo.
nest g module auth
Este comando crea un fichero auth.module.ts en el directorio src/auth y también actualiza el fichero app.module.ts.
Antes de seguir vamos a quitar los controladores y proveedores por defecto de nuestro código.
Para hacerlo borramos los ficheros app.controller.ts, app.controller.spec.ts y app.service.ts. También vamos a quitarlos del fichero app.module.ts.
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthModule } from './auth/auth.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 5000,
username: 'root',
password: 'codenip',
database: 'database',
autoLoadEntities: true,
synchronize: true,
}),
AuthModule,
],
})
export class AppModule {}
Ahora que teneos el modulo auth vamos a crear un controlador y un servicio.
nest g service auth
nest g controller auth
Si miramos en el editor vamos a ver que el cli nos ha creado los ficheros del controlador y el servicio y también dos ficheros de spec. Como en esta serie no hacemos tests vamos a quitar los ficheros spec.
Ahora vamos a crear la entidad y el repositorio del usuario dentro del modulo auth.
// src/auth/user.entity.ts
import { Entity } from 'typeorm';
@Entity()
export class User {}
// src/auth/user.repository.ts
import { Repository } from 'typeorm';
import { User } from './user.entity';
export class UsersRepository extends Repository {}
Y por ultimo tenemos que configurar el repositorio en el modulo auth.
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UsersRepository } from './users.repository';
@Module({
imports: [TypeOrmModule.forFeature([UsersRepository])],
controllers: [AuthController],
providers: [AuthService],
})
export class AuthModule {}
Esto es todo para esta semana.
Recuerda que tenemos esta misma serie en nuestro canal de youtube donde Juan explica muchas más cosas útiles.