Python 如何制作独立的API';s
我远不是这方面的专家,我的问题甚至可能毫无意义,但我正在尝试制作一个从我制作的服务器收集数据的应用程序。我制作了一个Python脚本,它可以登录到一个网站并从中获取数据。当您向API发出GET请求时,会调用Python函数,并将数据放在服务器上供应用程序获取。问题是:每当用户发出GET请求(甚至POST请求,以发送Python脚本登录所需的凭据)时,每个用户的服务器都会发生变化。例如,如果一个用户发布了他的凭据,那么每个人的字典“凭据”都会更改,如果第二个用户同时发布了他的凭据,那么字典可能会为两个用户中的一个获取错误的值。代码如下:Python 如何制作独立的API';s,python,json,api,flask,request,Python,Json,Api,Flask,Request,我远不是这方面的专家,我的问题甚至可能毫无意义,但我正在尝试制作一个从我制作的服务器收集数据的应用程序。我制作了一个Python脚本,它可以登录到一个网站并从中获取数据。当您向API发出GET请求时,会调用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()
撇开您将所有凭据都保存在内存中这一事实不谈,如果服务器崩溃,您将丢失一切 您不能使用字典来做任何您想做的事情,正如您已经知道的,字典只能保存同一个键的单个表示形式(在我们的例子中是“username”)。因此,当第二个用户调用
/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)
当然,维护令牌生命周期有点复杂,需要在一段时间后使令牌失效,并且您需要在每次请求时验证它(通常使用中间件),但这是一个概念。全局
credentials=dict()。你想使用或类似的方法来处理这个问题,所以你是说密码和用户名都应该在标题中?另外,如果您喜欢,您能给我指一个关于如何实现头的解释吗?非常感谢。不完全是这样,常用的方法是通过单向散列或令牌表示您的用户名和密码,并在其中一个头中发送令牌。用户使用用户名和密码登录服务器对用户进行身份验证,并向用户提供令牌,以便对客户端在指定标头中发送的每个API请求发出API请求,服务器验证令牌是否有效。您可以在此处阅读有关标题的更多信息: