Introducci贸n a Node.js y Express
Node.js y Express
Entorno de trabajo
Variables de entorno
Rutas din谩micas
Body parser
Postman
CRUD
驴Que es una API Restful?
Solicitudes GET
Solicitudes POST
CRUD
Soluci贸n del reto de validaci贸n
Solicitudes DELETE
MIddlewares
Middlewares - logger
Middlewares - ErrorHandler
DB
Instalar Postgresql
Instalar Prisma y PostgreSQL Client
Prisma Models
JWT
Autenticaci贸n utilizando JSON Web Tokens (JWT)
Auth - Register
Auth - Login
Expres.js
Arquitectura
Arquitectura parte 2
Creaci贸n y Migraci贸n de Modelos con Prisma para Citas M茅dicas
Admin controllers / services
Admin controllers / services parte 2
Reservations
Reservations parte 2
Appointments
Deploy
PostgreSQL
Deploy
You don't have access to this class
Keep learning! Join and start boosting your career
User authentication is a fundamental component of modern web application development. Implementing a robust system that allows users to register, login and access protected paths is essential to ensure the security of our applications. In this content, we will explore how to create a functional login endpoint using Node.js, Prisma and JSON Web Tokens.
When developing an API, we need to create an authentication system that allows users to access protected resources. To achieve this, we are going to implement a login endpoint that will verify the user's credentials and generate an authentication token.
Let's start by creating our endpoint in the main file:
app.post('/login', async (req, res) => { // Extract email and password from the request body const { email, password } = req.body;
// Find the user in the database const user = await prisma.user.findUnique({ where: { email } });
// Validate if the user exists if (!user) { return res.status(400).json({ error: "Invalid email or password" }); }
// Check if the password matches const validPassword = await bcrypt.compare(password, user.password);
// Validate if password is correct if (!validPassword) { return res.status(400).json({ error: "Invalid email or password" }); }
// Generate JWT token const token = jwt.sign( { id: user.id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '4h' } );
// Return token to client res.json({ token });});
This code performs several important operations:
A crucial aspect of authentication security is not to reveal specific information in error messages. Notice that in both validations (non-existent user and incorrect password) we return the same message: "Invalid email or password".
This is a fundamental security practice because:
If we were to display specific messages such as "Email does not exist" or "Password is incorrect", we would be giving valuable information to potential attackers.
Password verification is a critical process in any authentication system. In our code, we use bcrypt to compare the provided password with the one stored in the database:
const validPassword = await bcrypt.compare(password, user.password);
This line does all the heavy lifting:
true
if they match, false
if they don'tbcrypt is a specialized library that implements the Blowfish algorithm for password hashing, specifically designed to be slow and resistant to brute-force attacks.
JSON Web Tokens (JWT) are an open standard that defines a compact, self-contained way to securely transmit information between parties as a JSON object. This information can be verified because it is digitally signed.
In our code, we generate a JWT token with the following structure:
const token = jwt.sign( { id: user.id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '4h' });
This token contains:
The generated token will be used by the client to access protected routes. Each time the client makes a request to a protected route, it must include this token in the request headers.
To protect certain routes of our API, we need to implement a middleware that verifies the validity of the JWT token. This middleware will be executed before accessing the protected paths:
const authenticateToken = (req, res, next) => { const token = req.headers['authorization'];
if (!token) { return res.status(401).json({ error: "Access denied" }); }
try { const verified = jwt.verify(token, process.env.JWT_SECRET); req.user = verified; next(); } catch (error) { res.status(400).json({ error: "Invalid token" }); } } }; } };
// Protected path exampleapp.get('/protected', authenticateToken, (req, res) => { res.json({ message: "This path is protected" });});
This middleware:
To test our authentication implementation, we can use tools such as Postman. The test flow would be:
/register
./login
with the credentials/protected
and including the token in the headers.If everything works correctly, we should be able to access the protected path and receive the expected response.
It is important to remember that in a production environment, the frontend would be responsible for storing the token (usually in localStorage or cookies) and sending it on each request to protected routes.
The implementation of a robust authentication system is fundamental to protect our application resources. By following best practices and using proven libraries such as bcrypt and jsonwebtoken, we can create a secure and reliable system for our users.
Have you implemented authentication systems in your projects? What challenges have you faced? Share your experiences in the comments and let's keep learning together.
Contributions 0
Questions 0
Want to see more contributions, questions and answers from the community?