nban22 / Newspaper

Newspaper Web App: A dynamic online news platform with roles for guests, subscribers, writers, editors, and admins. Features include full-text search, category/tag filters, premium article access, WYSIWYG editor, and secure authentication using Express.js, TypeScript, MongoDB, and EJS
0 stars 0 forks source link

[Security and Data Handling] Password Encryption #31

Open nban22 opened 1 week ago

nban22 commented 1 week ago

Objective

Implement password encryption using bcrypt to securely store user passwords. This ensures that even if the database is compromised, the passwords cannot be easily accessed.


Requirements

  1. Install Bcrypt

    • First, install bcrypt (or bcryptjs for a pure JavaScript alternative) to hash passwords.

    Install Bcrypt:

    npm install bcrypt
  2. Hashing Passwords Before Saving

    • Modify the user registration process to hash the user's password before saving it to the database.
    • Ensure that the password is never stored in plaintext.

    Hash Password Example:

    const bcrypt = require('bcrypt');
    const saltRounds = 10;
    
    // Hash the password before saving the user
    const hashPassword = async (password) => {
     try {
       const hashedPassword = await bcrypt.hash(password, saltRounds);
       return hashedPassword;
     } catch (error) {
       console.error("Error hashing password:", error);
     }
    };
  3. User Registration

    • When a user registers, hash their password before saving it into the database.

    Registration Route Example:

    router.post('/register', async (req, res) => {
     const { name, email, password } = req.body;
    
     // Check if email already exists
     const existingUser = await User.findOne({ email });
     if (existingUser) {
       return res.status(400).send('Email is already taken');
     }
    
     // Hash the password
     const hashedPassword = await hashPassword(password);
    
     // Create and save the new user
     const newUser = new User({
       name,
       email,
       password: hashedPassword,
     });
    
     await newUser.save();
     res.status(201).send('User registered successfully');
    });
  4. Password Comparison During Login

    • When a user logs in, compare the entered password with the hashed password stored in the database.
    • Use bcrypt.compare() to check if the passwords match.

    Password Comparison Example:

    const bcrypt = require('bcrypt');
    
    // Compare entered password with stored hashed password
    const checkPassword = async (enteredPassword, storedHashedPassword) => {
     try {
       const isMatch = await bcrypt.compare(enteredPassword, storedHashedPassword);
       return isMatch;
     } catch (error) {
       console.error("Error comparing passwords:", error);
     }
    };

    Login Route Example:

    router.post('/login', async (req, res) => {
     const { email, password } = req.body;
     const user = await User.findOne({ email });
    
     if (!user) {
       return res.status(400).send('Invalid email or password');
     }
    
     // Compare entered password with stored hashed password
     const isMatch = await checkPassword(password, user.password);
    
     if (!isMatch) {
       return res.status(400).send('Invalid email or password');
     }
    
     // Proceed to login the user (e.g., create session or JWT)
     res.status(200).send('Logged in successfully');
    });
  5. Password Reset

    • When resetting a password, hash the new password before saving it.
    • Ensure the old password is never stored after the user changes it.

    Password Reset Route Example:

    router.post('/reset-password', async (req, res) => {
     const { email, newPassword } = req.body;
     const user = await User.findOne({ email });
    
     if (!user) {
       return res.status(400).send('Email not found');
     }
    
     // Hash the new password
     const hashedPassword = await hashPassword(newPassword);
    
     // Update password in the database
     user.password = hashedPassword;
     await user.save();
    
     res.status(200).send('Password reset successfully');
    });
  6. Salting

    • Bcrypt automatically generates a unique salt for each password and incorporates it into the hashing process. This helps ensure that even if two users have the same password, their hashed passwords will be different.
  7. Security Considerations

    • Ensure that password hashes are stored securely and that salt rounds are configured properly (e.g., 10 rounds is a good balance between security and performance).
    • Never log or expose raw password data, even in development environments.
    • Implement rate-limiting on login and registration endpoints to mitigate brute-force attacks.
  8. Update Password

    • If a user requests to change their password, validate the new password, hash it, and update the stored hash.

Deliverables


Acceptance Criteria

nban22 commented 5 days ago

ISSUE NÀY MỌI NGƯỜI ĐỌC VÀ FOLLOW THÔI, VÌ MẠT KHẨY MÌNH SẼ DÙNG SCHMA.PRE ĐỂ HASH NÊN ISSUE NÀY KO HẲN LÀ 1 TASK @Sang-Nguyen-Phuoc @LoiNguyennn @nxt964