Задать вопрос
@ch1ps01

Не получается сделать пост запрос на сервер, что делать?

from www import bp, csrf, app
from requests import get
from flask import render_template, Blueprint, request, jsonify
from json import loads
import hashlib
from bot import db
import hmac
from operator import itemgetter
from urllib.parse import parse_qsl
from os import getenv
from dotenv import load_dotenv
import datetime
from time import time
import jwt
from functools import wraps

load_dotenv()

SECRET_KEY = getenv('SECRET_KEY')
BOT_TOKEN = getenv('BOT_TOKEN')


def generate_token(user_id):
    payload = {
        'user_id': user_id,
        'exp': datetime.datetime.now() + datetime.timedelta(hours=1)
    }
    token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
    return token

def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = request.headers.get('Authorization')
        if not token or not token.startswith('Bearer '):
            return jsonify({'message': 'Token is missing or invalid!'}), 403

        try:
            token = token.split('Bearer ')[1]
            data = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
            current_user_id = data['user_id']
        except jwt.ExpiredSignatureError:
            return jsonify({'message': 'Token has expired!'}), 403
        except jwt.InvalidTokenError:
            return jsonify({'message': 'Invalid token!'}), 403

        return f(current_user_id, *args, **kwargs)
    return decorated

def check_webapp_signature(token: str, init_data: str):
    try:
        parsed_data = dict(parse_qsl(init_data))
    except ValueError:
        return False
    if "hash" not in parsed_data:
        return False

    hash_ = parsed_data.pop('hash')
    data_check_string = "\n".join(
        f"{k}={v}" for k, v in sorted(parsed_data.items(), key=itemgetter(0))
    )
    secret_key = hmac.new(
        key=b"WebAppData", msg=token.encode(), digestmod=hashlib.sha256
    )
    calculated_hash = hmac.new(
        key=secret_key.digest(), msg=data_check_string.encode(), digestmod=hashlib.sha256
    ).hexdigest()
    if calculated_hash == hash_:
        pairs = data_check_string.split('\n')
        data_dict = dict(pair.split('=') for pair in pairs)
        user_data = loads(data_dict['user'])

        return user_data

@app.route('/', methods=['POST', 'GET'])
def init():
    if request.method == 'GET':
        print('g')
        return render_template('init.html')
    elif request.method == 'POST':
        print('s')
        auth_header = request.headers.get('Authorization')
        print(auth_header)
        if not auth_header or not auth_header.startswith('Bearer '):
            return jsonify({'error': 'Authorization header missing or invalid'}), 400

        init_data = auth_header.split('Bearer ')[1]
        if not init_data:
            return jsonify({'error': 'No initData provided'}), 400

        res = check_webapp_signature(BOT_TOKEN, init_data)
        if res is not False:
            user = db.Users.query.filter_by(tg_id=int(res['id'])).first()
            if user:
                token = generate_token(res['id'])
                html = render_template('index.html', user=user)
                return jsonify({'html': html, 'token': token})
            else:
                return jsonify({'error': 'User not found'}), 404
        else:
            return jsonify({'error': 'Invalid init data'}), 400


это бэкэнд сервера, вкратце там настроен один марштрутизатор на адрес, при переходе на коренной адрес человеку возвращает такой шаблон init.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Market</title>
</head>
<body>
    <div class="loading-container">
        <div class="loader"></div>
        <div class="loading-text">Loading, please wait...</div>
    </div>
    <style>
        body, html {
            height: 100%;
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #1e1f24;
            font-family: Arial, sans-serif;
        }

        .loading-container {
            text-align: center;
        }

        .loader {
            border: 16px solid #f3f3f3;
            border-top: 16px solid #f3ca47;
            border-radius: 50%;
            width: 120px;
            height: 120px;
            animation: spin 2s linear infinite;
            margin: 0 auto;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .loading-text {
            margin-top: 20px;
            font-size: 18px;
            color: #555;
        }
    </style>

    <script src="https://telegram.org/js/telegram-web-app.js"></script>
    <script src="../static/js/auth.js"></script>
</body>
</html>


также вот файл auth.js

var tg = window.Telegram.WebApp;
tg.expand();
tg.ready();

//const initData = tg.initData;
const initData = 'query_id=AAGZHZtrAAAAAJkdm2srP0rs&user=%7B%22id%22%3A1805327769%2C%22first_name%22%3A%22Valentin%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22psh_valentin%22%2C%22language_code%22%3A%22ru%22%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1721550259&hash=8449f7f7e6b9be063aeade1b0b9f95f1d310ff97e4e44787835220a21e45ecdc'

document.addEventListener('DOMContentLoaded', function() {
    if (initData) {
        fetch('/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + initData
            },
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok ' + response.statusText);
            }
            return response.json();
        })
        .then(data => {
            const html = data.html;
            localStorage.setItem('token', data.token);
            document.open();
            document.write(html);
            document.close();
        })
        .catch((error) => {
            console.error('Error:', error);
        });
    } else {
        console.error('Not auth');
    }
});


в этом файле и заключается вся проблема, как вы можете заметить, берётся инитдата от телеграма ( щас там для дебага используется заготовленная инитдата ), она отправляется на сервер, где создаётся токен и возвращается обратно человеку, но проблема в том, что пост запрос не выполняется и я получаю ошибку 400

auth.js:10
POST 127.0.0.1:5000 400 (BAD REQUEST)
(anonymous) @ auth.js:10
auth.js:31 Error: Error: Network response was not ok BAD REQUEST
at auth.js:19:23
(anonymous) @ auth.js:31
Promise.catch
(anonymous) @ auth.js:30

сижу и не могу понять, в чём проблема и почему запрос не получается отправить, просто всё бы нечего, но пост запрос воощбе не обрабатывается на сервере, гет запрос обрабатывается, человеку возвращает шаблон init.html, а пост запрос вообще не обрабатівается потому что как вы можете заметить первая строка там print('s') и она также не выводится, заранее спасибо за ответ
  • Вопрос задан
  • 126 просмотров
Подписаться 1 Средний 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
@barolina
turn coffee into code
1. Неверный формат тела запроса
2. Проверте отправку запроса, через Postman/curl
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы