Failed to load resource: the server responded with a status of 422 (Unprocessable Entity)

Рейтинг: 0Ответов: 1Опубликовано: 15.01.2023

Пишу веб-сайт, и у меня возникает статус код 422, когда я вхожу в личный кабинет. Код питона:

import base64
from typing import Optional
import hmac
import hashlib
import json

from fastapi import FastAPI, Form, Cookie, Body
from fastapi.responses import Response


app = FastAPI()

SECRET_KEY = "c90c0420fc496cddc0fb2466daa8377a9c45d327acc2464aba86ed33f4ad7312"
PASSWORD_SALT = "3abffbad9c29fe3fd2d80374efbd415f988cfd0cfb764b3cfa872ed28a541548"

def sign_data(data: str) -> str:
    """Возвращает подписанные данные data"""
    return hmac.new(
        SECRET_KEY.encode(),
        msg=data.encode(),
        digestmod=hashlib.sha256
    ).hexdigest().upper()

def get_username_from_signed_string(username_signed: str) -> Optional[str]:
    username_base64, sign = username_signed.split(".")
    username = base64.b64decode(username_base64.encode()).decode()
    valid_sign = sign_data(username)
    if hmac.compare_digest(valid_sign, sign):
        return username

def verify_password(username: str, password: str) -> bool:
    password_hash = hashlib.sha256((password + PASSWORD_SALT).encode()).hexdigest().lower()
    stored_password_hash = users[username]['password'].lower()
    return password_hash == stored_password_hash

users = {
    "ochir@user.com": {
        "name": "Ochir",
        "password": "979fa622c981f0b3f2b5a931ca49ea741627a554fa3ff9618d391cb91376810d",
        "balance": 100000
    },
    "gektor@user.com": {
        "name": "Gektor",
        "password": "ac2e25f26b438cfb87a37afa9a1000682e46d8fc544b9312ebd2d694fc56ec3f",
        "balance": 200000
    }
}

@app.get('/')
def index_page(username: Optional[str] = Cookie(default=None)):
    with open('templates/login.html', 'r') as f:
        login_page = f.read()
    if not username:
        return Response(login_page, media_type="text/html")
    valid_username = get_username_from_signed_string(username) 
    if not valid_username:
        response = Response(login_page, media_type="text/html")
        response.delete_coolie(key="username")    
        return response  
    try:
        user = users[valid_username]
    except KeyError:
        response = Response(login_page, media_type='text/html')
        response.delete_cookie(key='username')
    return Response(f"Привет, {users[valid_username]['name']}<br />"
                    f"Баланс: {users[valid_username]['balance']}",
                    media_type='text/html')


@app.post('/login')
def process_login_page(data: dict = Body(...)):
    username = data["username"]
    password = data["password"]
    user = users.get(username)
    if not user or not verify_password(username, password):
        return Response(
            json.dumps({'success': False, 'message': 'уходи, незнакомец!'}), media_type="application/json")
    response = Response(json.dumps({
        'success': True,
        'message': f"Привет, {user['name']}!<br />Баланс: {user['balance']}"
    }), media_type='application/json')
    username_signed = base64.b64encode(username.encode()).decode() + "." + \
        sign_data(username)
    response.set_cookie(key='username', value=username_signed)
    return response

HTML-код:

<html>
    <head>
        <title>Личный кабинет</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <style type="text/css">
            input{
                display: block;
                font-size: 18px;
                padding: 15px;
                margin-bottom: 10px;
                outline: none;
                border: 1px solid #ccc;
                border-radius: 5px;
                width: 100%;
            }
            form{
                width: 90%;
                min-width: 250px;
                max-width: 350px;
            }
            body{
                margin: 0; padding: 0;
                width: 100%;
                height: 100%;
                display: flex;
                flex-direction: column;
                align-items: center;
                background-color: ghostwhite;
            }
            .placeholder{
                flex: 1;
            }
        </style>

        <script type="text/javascript">
            document.addEventListener("DOMContentLoaded", function(){
                let btn = document.querySelector('input[type=submit]');
                btn.addEventListener('click', async function(event){
                    event.preventDefault();
                    let username = document.querySelector('input[name=username]').value;
                    let password = document.querySelector('input[name=password]').value;
                    let response = await fetch("/login", {
                        method: "POST",
                        body:`{"username": "${username}", "password": "${password}"}`
                    });
                    let response_json = await response.json();
                    if (response_json.success){
                        let body = document.querySelector('body');
                        body.style.backgroundColor = "white";
                        body.style.display = "block";
                        body.innerHTML = response_json.message;
                    }
                })
            })
        </script>
    </head>
    <body>
        <div class="placeholder"></div>
            <form method="POST" action="/login">
                <input type="text" name="username" />
                <input type="password" name="password" />
                <input type="submit" value="Войти" />
            </form>
        <div class="placeholder"></div>
    </body>
</html>

Ошибка начала возникать после того, как я добавил в HTML-код данные в виде json в body: body:{"username": "${username}", "password": "${password}"}

Ответы

▲ 0

Решил данную проблему, вставил headers в let_response:

let response = await fetch("/login", {
               method: "POST",
               headers: {'Content-Type': 'application/json;charset=utf-8'},
               body:`{"username": "${username}", "password": "${password}"}`
                    });