No es mejor practica crear un LoginDto?
login(@Body() loginDTO: LoginDto) {
return this.authService.generateJWT(loginDTO);
}
Introducción
Cómo autenticar usuarios con NestJS
Instalación de PlatziStore con MongoDB
Instalación de PlatziStore con TypeORM
Protección con guardianes
Introducción a Guards
Usando un decorador
Guard con variables de ambiente
Autenticación con Passport
Hashing de contraseñas en TypeORM
Hashing de contraseñas en MongoDB
Autenticación con Passport.js
Ruta de login
Autenticación con JSON Web Tokens
Conectando Passport con JWT
Secret desde variables de entorno
Implementando JWT Guard
Extendiendo JWT Guard
Control de roles en NestJS
Obteniendo órdenes del perfil
Deployment
Configurando Mongo Atlas
Deploy de Mongo en Heroku
Configuración de PostgreSQL en Heroku
Deploy de Postgres en Heroku
Corriendo migraciones de Postgres en Heroku
Próximos pasos
¿Quieres más cursos de NestJS?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Nicolas Molina
Aportes 18
Preguntas 10
No es mejor practica crear un LoginDto?
login(@Body() loginDTO: LoginDto) {
return this.authService.generateJWT(loginDTO);
}
Creo que el codigo del final del metodo validateUser quedaria mas limpio si lo tenemos de la siguiente manera:
async validateUser(email: string, password: string) {
const user = await this.usersService.findByEmail(email)
if (!user) {
return null
}
const isMatch = await bcrypt.compare(password, user.password)
if (isMatch) {
const { password, ...rta } = user.toJSON()
return rta
}
return null
}
En vez de usar if’s nidados, mejor tenemos un early return. Asi nos aseguramos que user exista y podemos acceder a user.password.
En mongo puedes pasar un segundo parametro al find o findOne que te permite ocultar o mostrar los campos que te devuelve la consulta, para el caso seria:
userModel.find({ email: email }, { password: 0 } )
Estuve teniendo un 401 “not allow” al intentar loguearme y lo corregí de la siguiente manera.
El problema que tenía venía de src/users/users.service.ts
En el código que venimos trabajando la conuslta por email está de la siguiente forma:
findByEmail(email: string) {
return this.userModel.findOne({ email }).exec();
}
Mi problema era que nunca podía loguearme, la razon es que la consulta a la BD es una promesa que no se resolvía antes de continuar con el flujo. Obteniendo siempre un user=null.
Desde entonces la tengo como una función asíncrona. Ej:
async findByEmail(email: string) {
const userEncontrado = await this.userModel.findOne({ email }).exec();
return userEncontrado;
}
De ésta forma resolví el problema que tenía. Lo dejo acá por si alguno tiene el mismo problema.
Saludos
Me salio este error cuando intente de ejecutar la aplicación, encontre que tenia que ver con el namespace, pero las soluciones estaban muy confusas, pero en la documentación hay otro metodo sin usar express.
import { Controller, Post, Request, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('auth')
export class AuthController {
@UseGuards(AuthGuard('local'))
@Post()
login(@Request() req) {
return req.user;
}
}
En el controlador importamos de common el decorador Request y nuestra función login colocamos el decorador con el “req” y funciona igual. 😸
nest generate controller auth/controllers/auth
Para evitar enviar información sensible en mi respuesta del controlador (passwords, etc) la mejor técnica es serializar, defino desde mi entity que info no debo compartir asi evito tener que hacer modificaciones de mi respuesta en cada enpoint https://platzi.com/clases/2282-nestjs-typeorm/37326-serializar/
Esta Clase, al finalizar…salta a “Configurando mongo atlas” y no a “conectando passport con jwt”.
Usando Postgrest con Swagger
Usuario con datos erróneos:
Usuario con datos correctos:
Para configurar vscode para debuguear el código, demos:
Ir a a la pestaña Run and Debug o Ctrl + Shipt + D
Crear un archivo launch.json con create a launch.json file.
Pegar el siguiente código.
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${file}",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
}
]
}
En la pestaña Run and Debug abrimos la lista desplegable, seleccionamos Run Script: start:debug
Dejamos que nuestro sistema transpile.
Una vez terminada la transpilación, podremos debuguear nuestro código con nestjs.
nest g co auth/controllers/auth --flat
hice una cambio de estructura en la validación para una mejor lectura del código, se las comparto:
async validateUSer(email: string, password: string) {
const user = await this.userService.findByEmail(email);
if (!user) {
return null;
}
const isMatch = await bcrypt.compare(password, user.password);
return isMatch ? user : null;
}
Les dejo por aca algo que hice para reciba email o username, espero les sirva
async findOneByEmailOrUsername(username: string) {
const type = isEmail(username);
if (type) {
return await this.usersRepository.findOne({
where: { email: username },
});
}
if (!type) {
return await this.usersRepository.findOne({
where: { username },
});
}
}
Login exitoso
Login fallido
👏
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?