# Sequelize User Authentication

1. **<mark>Introduction</mark>**  
    Implementing user authentication in Node.js with PostgreSQL involves creating a secure system to register users, authenticate them, and manage sessions or tokens. User authentication with **Sequelize**, **PostgreSQL**, **Node.js**, and **JWT (JSON Web Tokens)** involves several steps, including user registration, password hashing, and JWT generation for secure authentication.
    
2. **<mark>Set Up the Environment</mark>**  
    You'll need to set up the environment with the following tools:
    
    **Node.js** - For running JavaScript on the server.
    
    **PostgreSQL** - As the relational database to store user data.
    
    **Sequelize** - As an ORM (Object-Relational Mapper) for interacting with PostgreSQL.
    
    **JWT** - For secure token-based authentication.
    
    **bcryptjs** - For hashing passwords.  
    
    Install the necessary packages
    
    ```bash
    npm install express sequelize pg pg-hstore jsonwebtoken bcryptjs
    ```
    
    #### Initialize Sequelize
    
    Set up Sequelize by creating models and connecting it to your PostgreSQL database.
    
    ```javascript
    const { Sequelize, DataTypes } = require('sequelize');
    
    // Initialize the Sequelize connection
    const sequelize = new Sequelize('postgres://username:password@localhost:5432/mydatabase');
    
    // Define the User model
    const User = sequelize.define('User', {
      username: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
      },
      email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
      },
      password: {
        type: DataTypes.STRING,
        allowNull: false,
      },
    }, {
      timestamps: true,
    });
    
    // Sync the model with the database
    sequelize.sync();
    ```
    
3. **<mark>User Registration</mark>**
    
    During registration, the user’s password is hashed using `bcryptjs` before storing it in the database.
    
    ```javascript
    javascript
    Copy code
    const bcrypt = require('bcryptjs');
    
    // User registration route
    app.post('/register', async (req, res) => {
      const { username, email, password } = req.body;
    
      // Hash the password
      const hashedPassword = await bcrypt.hash(password, 10);
    
      try {
        // Create a new user in the database
        const newUser = await User.create({
          username,
          email,
          password: hashedPassword,
        });
    
        res.status(201).json({ message: 'User registered successfully' });
      } catch (error) {
        res.status(500).json({ error: 'Error registering user' });
      }
    });
    ```
    
4. **<mark>User Login and JWT Generation</mark>**
    
    When the user logs in, the provided password is compared with the hashed password stored in the database using `bcryptjs`. If the passwords match, a JWT is generated and sent back to the user.
    
    ```javascript
    const jwt = require('jsonwebtoken');
    
    // User login route
    app.post('/login', async (req, res) => {
      const { email, password } = req.body;
    
      try {
        // Find the user by email
        const user = await User.findOne({ where: { email } });
        
        if (!user) {
          return res.status(404).json({ error: 'User not found' });
        }
    
        // Compare the provided password with the stored hashed password
        const isMatch = await bcrypt.compare(password, user.password);
    
        if (!isMatch) {
          return res.status(401).json({ error: 'Invalid password' });
        }
    
        // Generate a JWT
        const token = jwt.sign({ userId: user.id }, 'your_jwt_secret', { expiresIn: '1h' });
    
        res.status(200).json({ message: 'Login successful', token });
      } catch (error) {
        res.status(500).json({ error: 'Error logging in' });
      }
    });
    ```
    
5. **<mark>JWT Authentication Middleware</mark>**
    
    To protect routes, create a middleware function that verifies the JWT sent in the request headers.
    
    ```javascript
    const jwt = require('jsonwebtoken');
    
    // Middleware to authenticate JWT
    const authenticateToken = (req, res, next) => {
      const token = req.headers['authorization'];
    
      if (!token) {
        return res.status(403).json({ error: 'Access denied' });
      }
    
      try {
        const verified = jwt.verify(token, 'your_jwt_secret');
        req.userId = verified.userId;
        next();
      } catch (error) {
        res.status(401).json({ error: 'Invalid token' });
      }
    };
    
    // Example of a protected route
    app.get('/protected', authenticateToken, (req, res) => {
      res.status(200).json({ message: 'This is a protected route' });
    });
    ```
    
6. **<mark>Putting It All Together</mark>**
    
    ```javascript
    /auth-app
      /node_modules
      /config
        database.js
      /models
        user.js
      /routes
        auth.js
      /middleware
        authMiddleware.js
      app.js
      package.json
    ```
    
    **User registers** with a hashed password.
    
    **User logs in**, password is verified, and a JWT is generated.
    
    **Protected routes** are accessible only with a valid JWT.
