API responses with 422 on login request

Question:

I want to login a user via a form and a API request. But I allways get a 422 Error, and I can’t locate the faulty code.

The API is written with FastAPI in python.
This is the Swagger API documentation.


When I try to login via Swagger it works and I get a 200.

FastAPI written in Python

@router.post("/login", status_code=status.HTTP_200_OK, response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(),
                             db: Session = Depends(get_db)):
user = authenticate_user(form_data.username, form_data.password, db)
if not user:
    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Incorrect username or password",
        headers={"WWW-Authenticate": "Bearer"},
    )

access_token_expires = timedelta(minutes=60)
access_token = create_access_token(
    data={"sub": user.username}, expires_delta=access_token_expires
)
check_password_expiration(user)
if user.change_password:
    return {"access_token": access_token,
            "token_type": "bearer",
            "message": "Password expired, please set new password"}
return {"access_token": access_token, "token_type": "bearer"}

Javascript API Request

function loginRequest(username_value, password_value) {
var data = new FormData();
data.append("username", username_value);
data.append("password", password_value);

for (var pair of data.entries()) {
    console.log(pair[0] + ', ' + pair[1]);
}

fetch("https://www.example-url.net", {
    method: "POST",
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: data
})
.then(response => {
    console.log(response.json())
})
}

With that request, I get a 422 Error.

If I take a look into the console I get the body

enter image description here

At which Point is the server not able to process the request body? Why are the values not correctly processed?

PS: I know that I get a jwt in return and I’m not processing that one yet. But in the first step I would like to make a successfull API Call.

Asked By: Flo

||

Answers:

With Swagger the data is probably uri-encoded for you. But with js fetch and application/x-www-form-urlencoded, this is not the case. Since your password contains an asterisk (*), you might want to uri-encode it first, using:

encodeURIComponent(password_value)

before sending the data to the server.

Answered By: Klaassiek

I prefer you to use multipart/form-data then application/x-www-form-urlencoded format. As using multipart/form-data request content-type you can send FormData object directly and on server it will read as a form-data and you are good to go. But If you want to pass form-data in application/x-www-form-urlencoded you need to pass it using URLSearchParams. You can try this:

const data = new URLSearchParams(new FormData(formElement));

The problem was outside my code I posted. There was something blocking the payload between server and api domain/ssl redirection. I still don’t know what exactly, but the space of possible solutions is outside the problem I posted here.

Answered By: Flo
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.