Modern Enterprise Software Applications are implemented with a backend following the Http Rest Api pattern. Each request must include an "Authorization" header with a Bearer Token as value. JWT tokens are becoming the more secure way to authenticate requests. The most common way to get a JWT from the Backend Application is implementing an "authenticate" endpoint that receives the User's username and password. You can use the endpoint provided by the lexik/jwt-authentication-bundle or you can implement your own. Follow these steps to do this:

Prerequisites: How to generate a JWT json web token in symfony framework.

Step 1. Install the necessary packages:

composer require lexik/jwt-authentication-bundle
composer require symfony/security-bundle

 Step 2. Configure your security.yaml file by adding the following lines:

security:
    encoders:
        App\Entity\User:
            ### lib-sodium available in your machine
            ### If not use bcrypt
            algorithm: sodium

    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                ###This is the username
                property: email

    firewalls:
        login:
            pattern: ^/api/login
            stateless: true
            anonymous: true
            json_login:
                check_path: /api/login
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

    access_control:
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

 Step 3. Create a route for handling the login request in your routes.yaml file or you may better use the new recommended way with Symfony Annotations as shown in Step 4.:

login:
    path: /api/login
    controller: App\Controller\AuthController::login

 Step 4. Create an AuthController class and implement the login method:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class AuthController extends AbstractController
{
    /**
     * @Route("/api/login", methods={"POST"}, defaults={"_format": "json"})
     * @param Request $request
     * @param JWTTokenManagerInterface $jwtManager
     * @param UserPasswordEncoderInterface $passwordEncoder
     * @param EntityManagerInterface $em
     * @return JsonResponse
     */
    public function login(Request $request, JWTTokenManagerInterface $jwtManager, UserPasswordEncoderInterface $passwordEncoder, EntityManagerInterface $em)
    {
        $user = $em->getRepository(User::class)->findOneBy(['email' => $request->request->get('username')]);
        
        if (!$user) {
            throw new BadCredentialsException();
        }
        
        $isValid = $passwordEncoder->isPasswordValid($user, $request->request->get('password'));
        
        if (!$isValid) {
            throw new BadCredentialsException();
        }
        
        $token = $jwtManager->create($user);
        
        return new JsonResponse(['token' => $token]);
    }
}

Step 5.  Test your endpoint by sending a POST request to /api/login with a JSON payload containing the username and password fields:

{
  "username": "This email address is being protected from spambots. You need JavaScript enabled to view it.",
  "password": "password123"
}

 Important!: As best practice and to prevent security breaches, send hashed passwords with an algorithm that can be implemented in the frontend application that can be de-hashed by the backend.