Get 422 error when trying to connect frontend to server

I am using fastapi-users library for authentication and authorization. Everything worked properly in swagger but when I am trying to connect backend and frontend i get such an error and such data:
[HTTP/1.1 422 Unprocessable Entity 8ms]

request: {"username":"[email protected]","password":"me"}
response: {"detail":[{"type":"missing","loc":["body","username"],"msg":"Field required","input":null},{"type":"missing","loc":["body","password"],"msg":"Field required","input":null}]}

I added CORS and MiddleWare, so it should be ok there.

origins = [
        f"http://{FRONT_HOST}:{FRONT_PORT}",
    ]
app.add_middleware(
        CORSMiddleware,
        allow_origins=origins,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

Here is my Login code:

import React, { useState } from 'react';

const Login = () => {
  const [formData, setFormData] = useState({
        username: '',
        password: '',
    });


  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');

  const handleChange = (e) => {
        const { name, value } = e.target;
        setFormData({
            ...formData,
            [name]: value,
        });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();

    try {
        const response = await fetch('http://localhost:8000/auth/jwt/login', {
            method: "POST",
            headers: {
                'accept': 'application/json',
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: JSON.stringify({
                username: formData.username,
                password: formData.password})
        });

        if (!response.ok) {
            throw new Error('Error during registration');
        }

        const data = await response.json();
        setSuccess('Login successful!');
        return <Redirect to='/account' />;
        // Возможно, вам нужно будет перенаправить пользователя или обновить состояние приложения


    } catch (err) {
        setError(err.message);
    }
  };

  return (
    <form onSubmit={handleSubmit} style={{ maxWidth: '400px', margin: 'auto' }}>
      <h2>Login</h2>
        <div>
          <label>Email:</label>
          <input
            type="email"
            name="username"
            value={formData.username}
            onChange={handleChange}
            required
          />
        </div>
        <div>
          <label>Password:</label>
          <input
            type="password"
            name="password"
            value={formData.password}
            onChange={handleChange}
            required
          />
        </div>
        <button type="submit">Enter</button>
    </form>
  );
}

export default Login;

I read the github code of OAuth2PasswordRequestForm but still cannot understand what is the root of this problem.

I’ve tried different variations of:

  • body parameter in fetch (JSON.stringify, and just formData)
  • tried to add other optional parameters (grant_type, scope, client_id, client_secret)
  • tried to use both “application/x-www-form-urlencoded” and “application/json” content types

Maybe I do not understand how forms and JSON are sent.
I think there is a problem in sending data.
I would be glad to find out how it should actually work because I am new to making fullstack.