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

Почему вечная загрузка ответа при использовании мидлвара?

Добрый день всем, я столкнулся с проблемой, когда начал создавать промежуточное программное обеспечение авторизации, чтобы каждый сервис при общении имел в заголовках токен авторизации пользователя и его идентификатор. Проблема возникла, когда я попытался отправить некоторые данные JSON в почтовом запросе.

При отправке прямого запроса к конечному сервису (пользователю) через POST с передачей параметров, я получаю корректный ответ.
При отправке запроса через промежуточное ПО авторизации у меня происходит бесконечная загрузка.
Если мы используем "data = request.get_json()" (строка 19 в main.py) - код работает и выдает ответ, но без данных json.
Если мы не передаем ничего в json, я получаю ошибку в main.py:
Error handling POST: 400 Bad Request: Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)

Нет разницы, отправлять через postman или через curl.

Код
Node.JS Auth Service main.js:
const express = require('express');
const axios = require('axios');
const app = express();
const services = require('./services');

app.use(express.json());

async function validateToken(authToken) {
    const user_service = services.find((service) => {
        return service.name === 'user';
    });

    const user_service_url = `${user_service.protocol}://${user_service.host}:${user_service.port}`;
    const request_url = `${user_service_url}/validate_token`;

    try {
        console.log(`Making request to ${request_url} with token ${authToken}`);
        const response = await axios.post(request_url, {}, { headers: { Authorization: authToken } });
        return response.data;
    } catch (error) {
        console.log(error);
        return null;
    }
}

app.get('*', async (req, res) => {
    let url = req.url;

    if (url.indexOf('/auth/') !== 0) {
        return res.send('Authentication not completed!');
    }

    url = url.split('/auth')[1];

    const service = services.find((service) => {
        return url.indexOf(`/${service.name}`) === 0;
    });

    if (!service) {
        return res.send('Service not found!');
    }

    const servicePath = `/${service.name}`;
    const urlParts = url.split(servicePath);

    if (urlParts.length < 2) {
        return res.send('Invalid URL format');
    }

    const requestPath = urlParts.slice(1).join(servicePath);
    const request_url = `${service.protocol}://${service.host}:${service.port}${requestPath}`;


    // Check if the request has a token
    if (req.headers.authorization) {
        let response = await validateToken(req.headers.authorization);

        if (!response.token_valid) {
            req.headers.authorization = null;
        } else {
            req.headers.Userid = response.user_id;
            console.log(response);
        }
    }

    try {
        const response = await axios.get(request_url, { headers: req.headers });
        res.send(response.data);
    } catch (error) {
        res.status(500).send('Error while making the request');
        console.log(error);
    }
});

app.post('*', async (req, res) => {
    let url = req.url;

    if (url.indexOf('/auth/') !== 0) {
        return res.send('Authentication not completed!');
    }

    url = url.split('/auth')[1];

    const service = services.find((service) => {
        return url.indexOf(`/${service.name}`) === 0;
    });

    if (!service) {
        return res.send('Service not found!');
    }

    const servicePath = `/${service.name}`;
    const urlParts = url.split(servicePath);

    if (urlParts.length < 2) {
        return res.send('Invalid URL format');
    }

    const requestPath = urlParts.slice(1).join(servicePath);
    const request_url = `${service.protocol}://${service.host}:${service.port}${requestPath}`;


    // Check if the request has a token
    if (req.headers.authorization) {
        let response = await validateToken(req.headers.authorization);

        if (!response.token_valid) {
            req.headers.authorization = null;
        } else {
            req.headers.Userid = response.user_id;
            console.log(response);
        }
    }

    let modifiedHeaders = {...req.headers};
    delete modifiedHeaders.host;

    try {
        console.log("Making POST request to Flask:", request_url, req.body, modifiedHeaders);
        const response = await axios.post(request_url, req.body, {
            headers: modifiedHeaders,
            params: req.query
        });
        console.log("Response from Flask:", response.status, response.data);
        res.send(response.data);
    } catch (error) {
        console.error("Error making POST request to Flask:", error);
        res.status(500).send('Error while making the request');
    }
});

app.listen(services[0].port, () => {
    console.log(`Example app listening on port ${services[0].port}!`);
});


Node.js services.js:
const services = [
    {
        name: 'auth',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3000,
    },
    {
        name: 'weather',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3001,
    },
    {
        name: 'routes',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3002,
    },
    {
        name: 'places',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3003,
    },
    {
        name: 'travel',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3004,
    },
    {
        name: 'community',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3005,
    },
    {
        name: 'support',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3006,
    },
    {
        name: 'reviews',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3007,
    },
    {
        name: 'user',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3008,
    },
    {
        name: 'dwelling',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3009,
    },
    {
        name: 'search',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3010,
    },
    {
        name: 'recommendation',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3011,
    },
    {
        name: 'notification',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3012,
    },
    {
        name: 'transport',
        protocol: 'http',
        host: '127.0.0.1',
        port: 3013,
    }
]

module.exports = services;


Python Flask main.py:
from flask import request, jsonify, Flask
from flask_cors import CORS

app = Flask(__name__)

# CORS(allow_headers='Content-Type')
# CORS(app, resources={r"/*": {"origins": "*"}})


@app.route('/user', methods=['GET'])
def get_user():
    return jsonify({'user_id': request.headers.get('Userid'), 'token': request.headers.get('Authorization')})


@app.route('/user', methods=['POST'])
def create_user():
    try:
        print('Handling POST request')
        data = request.get_json()
        print('Data received:', data)
        return jsonify({'user_id': request.headers.get('Userid'), 'token': request.headers.get('Authorization')})
    except Exception as e:
        print("Error handling POST:", str(e))
        return jsonify({'error': str(e)}), 500


@app.route('/user', methods=['PUT'])
def update_user():
    return jsonify({'user_id': request.headers.get('Userid'), 'token': request.headers.get('Authorization')})


@app.route('/user', methods=['DELETE'])
def delete_user():
    return jsonify({'user_id': request.headers.get('Userid'), 'token': request.headers.get('Authorization')})


@app.route('/validate_token', methods=['POST'])
def validate_token():
    token = request.headers.get('Authorization')

    # TODO: Real validate token logic
    if token is None:
        return jsonify({'user_id': None, 'token_valid': False})

    elif token == 'test':
        return jsonify({'user_id': 1, 'token_valid': True})

    else:
        return jsonify({'user_id': None, 'token_valid': False})


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=3008, debug=True, threaded=False)


Если мы используем метод get — все ок (но без тела json), а также если мы не используем службу аутентификации и делаем прямой запрос к серверу flask (но в этом случае я не могу получить идентификатор пользователя и токен аутентификации)
  • Вопрос задан
  • 222 просмотра
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

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

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