【发布时间】:2020-05-12 16:18:28
【问题描述】:
我打算为数据库中的每个用户返回个性化令牌;为此,我尝试在for 循环中迭代用户列表并检查当前用户是否在数据库表中,如果是,GET 方法将返回令牌值。我使用postgresql 和psycopg2,我使用fetchall() 来获取数据库表中的所有实例,但我需要迭代每一行并检查它是否在数据库中。我尝试了 for 循环,但在端点出现以下错误:
curl -X GET --header 'Accept: application/json' 'http://127.0.0.1:5000/token?username=tom%20hardy&password=password3'
http://127.0.0.1:5000/token?username=tom%20hardy&password=password3
响应正文中的错误消息:
{
"message": "Username: tom hardy doesn't exist. You have requested this URI [/token] but did you mean /token ?"
}
这不是真的,因为请求正文中的用户实际上是在数据库中。我假设迭代 fetchall() dict 在下面的代码尝试中不起作用。如何使这项工作?
postgresql 数据库:
CREATE TABLE authorized_user_table(
user_id serial PRIMARY KEY,
username VARCHAR (50) UNIQUE NOT NULL,
password VARCHAR (50) NOT NULL
);
insert into authorized_user_table(user_id,username,password) values
(1,'jen hank','password'),
(2,'andy roy','password2'),
(3, 'tom hardy', 'password3'),
(4, 'shah khan', 'password4');
我的后端代码
from flask_restplus import Resource, Api, Namespace
from flask_restplus import abort, fields, inputs, reqparse
from psycopg2 import sql
from flask import Flask, request, jsonify
import psycopg2, json, request
app = Flask(__name__)
api = Api(app)
credential_parser = reqparse.RequestParser()
credential_parser.add_argument('username', type=str)
credential_parser.add_argument('password', type=str)
@api.route('/token')
class Token(Resource):
@api.response(200, 'Successful')
@api.doc(description="Generates a authentication token")
@api.expect(credential_parser, validate=True)
def get(self):
args = credential_parser.parse_args()
username = args.get('username')
password = args.get('password')
cursor = db.cursor()
cursor.execute('SELECT * FROM public.authorized_user_table')
users = cursor.fetchall()
for user in users:
if username != user[1]: ## user[1] gives username
api.abort(404, "Username: {} doesn't exist".format(username))
if password != user[2]:
api.abort(401, "Wrong password")
return {"token": generate_token(username)
def generate_token(self, username):
info = {
'username': username,
'creation_time': time()
}
token = self.serializer.dumps(info)
return token.decode()
if __name__ == '__main__':
db = psycopg2.connect(database='test_db', user='postgres', password='password', host='localhost', port="5432")
app.run(debug=True)
在上面的代码中迭代fetchall() dict 仍然不令人满意。我应该如何迭代它们?有什么办法可以做到这一点?谢谢
【问题讨论】:
-
@snakecharmerb 我不确定这是否有效。这和我试图做的一样吗?如果是,如何处理异常或数据库错误?我们可以在条件语句中使用
cursor.execute('SELECT * FROM public.authorized_user_table WHERE username = %s', user[1] )吗?谢谢 -
@snakecharmerb 如果我的上述尝试不是最佳的,有没有更好的方法来提高效率?感谢您的帮助
-
实际上,您可以使用
cursor.execute('SELECT * FROM public.authorized_user_table WHERE username = %s AND password = %s', (username, password) )从数据库中获取与请求中的用户名和密码匹配的所有行。理想情况下,这将返回一或零行 -
对不起,我在原始评论中使用了错误的变量名
-
@snakecharmerb 这不应该是问题。我明白你的意思,但我想知道如何验证用户是否在数据库中。如果可能的话,您介意发布可行的解决方案吗?再次感谢
标签: python postgresql flask psycopg2