You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesi贸n a prueba de IA

Antes: $249

Currency
$209
Suscr铆bete

Termina en:

0 D铆as
14 Hrs
43 Min
30 Seg
Curso de Backend con ExpressJS

Curso de Backend con ExpressJS

Oscar Barajas Tavares

Oscar Barajas Tavares

Auth - Login

20/30
Resources

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.

How to implement a secure login endpoint?

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:

  1. Extracts the credentials from the request body.
  2. Searches for the user in the database using Prisma
  3. Verifies the password using bcrypt
  4. Generates a JWT token with relevant user information
  5. Returns the token to the client for further use

Why is error message security important?

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:

  • It prevents attackers from determining whether a specific email is registered.
  • Provides no clues as to which of the credentials is incorrect
  • Makes brute-force or user enumeration attacks more difficult

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.

How does password verification with bcrypt work?

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:

  • It takes the plaintext password from the request.
  • Compares it with the hashed version stored in the database.
  • Returns true if they match, false if they don't

bcrypt is a specialized library that implements the Blowfish algorithm for password hashing, specifically designed to be slow and resistant to brute-force attacks.

What are JSON Web Tokens and how to implement them?

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:

  1. Payload: User information (ID and role).
  2. Signature: Created with a secret key stored in environment variables
  3. Expiration time: Set to 4 hours

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.

How to protect routes with authentication middleware?

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:

  1. Extracts the token from the request headers.
  2. Checks its validity using the secret key
  3. Attaches the user's information to the request object for later use
  4. Allows to continue with the request if the token is valid

How to test our authentication API?

To test our authentication implementation, we can use tools such as Postman. The test flow would be:

  1. Register a user by sending a POST request to /register.
  2. Login by sending a POST request to /login with the credentials
  3. Copy the token received in the response
  4. Access a protected path by sending a GET request to /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

Sort by:

Want to see more contributions, questions and answers from the community?