Как мне сделать независимые API? - PullRequest
0 голосов
/ 03 мая 2020

Я далеко не эксперт по топикам c, и мой вопрос может даже не иметь смысла, но я пытаюсь создать приложение, которое собирает данные с созданного мной сервера. Я создал скрипт Python, который входит на веб-сайт и удаляет с него данные. Когда вы отправляете запрос GET к API, вызываются функции Python, и данные помещаются на сервер, чтобы приложение могло их принять. Дело в том, что всякий раз, когда пользователь отправляет запрос GET (или даже запрос POST, чтобы отправить учетные данные, необходимые для входа в сценарий Python), сервер меняется для каждого пользователя. Например, если пользователь публикует свои учетные данные, словарь «учетные данные» изменяется для всех, и если второй пользователь одновременно публикует свои учетные данные, словарь может получить неправильные значения для одного из двух пользователей. Вот код:

from flask import Flask, request, jsonify
import backend as b

app = Flask(__name__)
credentials = dict()
subjectNames = ['Italiano', 'Inglese', 'Filosofia', 'Storia', 'Matematica', 'Informatica', 'Fisica', 'Scienze', 'Arte', 'Educazione Fisica']

@app.route('/login', methods=['POST'])
def getCredentials():
    if request.method == 'POST':
        username = request.get_json(force=True).get('username')
        password = request.get_json(force=True).get('password')
        credentials['username'] = username
        credentials['password'] = password
        return jsonify({'credentials': credentials})


@app.route ('/creds', methods=['GET'])
def creds():
    return jsonify({'credentials': credentials})

@app.route('/api', methods=['GET'])
def api():
    if request.method == 'GET':
        query = str(request.args['query'])
        if query == 'marks':
            d = {}
            m = b.getFullMarks(b.login(credentials['username'], credentials['password']))
            for i in range(len(subjectNames)):
                d[subjectNames[i]] = m[i]
            return jsonify(d)
        elif query == 'names':
            d = {}
            m = b.getNames(b.login(credentials['username'], credentials['password']))
            for i in range(len(subjectNames)):
                d[subjectNames[i]] = m[i]
            return jsonify(d)
        elif query == 'calendar':
            d = {}
            m = b.calendar(b.login(credentials['username'], credentials['password']))
            d['Calendar'] = m
            return jsonify(d)
        elif query == 'badge':
            d = {}
            m = b.badge(b.login(credentials['username'], credentials['password']))
            d['Badge'] = m
            return jsonify(d)

if __name__ == '__main__':
    app.run()

1 Ответ

1 голос
/ 03 мая 2020

Оставляя в стороне тот факт, что вы храните все учетные данные в памяти, и если сервер выходит из строя, вы потеряли все.

Вы не можете использовать словарь, чтобы делать, как вы хотите, как вы уже знаете словарь может содержать только одно представление одного и того же ключа (в нашем случае, «имя пользователя»). поэтому, когда второй пользователь вызывает конечную точку /login, вы перезаписываете предыдущую и наоборот.

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

Вы можете искать существующие реализации или делать что-то самостоятельно. но в конечном итоге вам необходимо сопоставить токен с пользователем, например:

@app.route('/login', methods=['POST'])
def getCredentials():
    if request.method == 'POST':
        username = request.get_json(force=True).get('username')
        password = request.get_json(force=True).get('password')
        token = generate_token_for_user(username, password)
        credentials[token] = {'username': username, 'password': password}
        return jsonify({'token': token})

и в вызове API:

@app.route('/api', methods=['GET'])
def api():
    token = request.headers['Authorization'] # assuming you're using this for your token
    creds = credentials.get(token)
    d = {}
    if request.method == 'GET':
        query = str(request.args['query'])
        if query == 'marks':
            m = b.getFullMarks(b.login(creds['username'], creds['password']))
            for i in range(len(subjectNames)):
                d[subjectNames[i]] = m[i]
            return jsonify(d)
        elif query == 'names':
            m = b.getNames(b.login(creds['username'], creds['password']))
            for i in range(len(subjectNames)):
                d[subjectNames[i]] = m[i]
            return jsonify(d)
        elif query == 'calendar':
            m = b.calendar(b.login(creds['username'], creds['password']))
            d['Calendar'] = m
            return jsonify(d)
        elif query == 'badge':
            m = b.badge(b.login(creds['username'], creds['password']))
            d['Badge'] = m
            return jsonify(d)

Offcourse, что поддержание жизненного цикла токена является немного сложнее, нужно через некоторое время аннулировать токен, и вам нужно будет проверять его при каждом запросе (обычно с промежуточным программным обеспечением), но это концепция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...