为Flask创建身份验证装饰器时遇到的问题

时间:2019-02-08 03:06:03

标签: python python-3.x flask python-decorators

我正在尝试为我的所有烧瓶app.routes设置身份验证装饰器。每次调用与路由相关的功能时,我都会检查请求是否传递了正确的密钥。

我已经创建了一个装饰器(这可能是错误的)。首先,它说它没有配置返回值,后来我修复了该返回值。当我尝试再次运行它时,错误提示:

  

“ TypeError:unregisterApi()接受0个位置参数,但给出了2个   视图函数未返回有效响应。返回类型必须是字符串,元组,Response实例或可调用的WSGI,但这是一个函数。   “。

我确定问题是我的装饰器,但我不知道如何解决。

这是装饰器和装饰函数的代码:

装饰器:

def requestAuth(func):
   def funcWrapper():
       data = request.get_json(force=True)
       apiAddr = request.remote_addr
       apiKey = data["API Register Key"]

       conn = sqlite3.connect("database/controllerConfiguration.db")
       cursor = conn.cursor()
       cursor.execute('select apikey from SystemAPI where apihost  = \"{0}\";'.format(apiAddr))
       result = cursor.fetchall()
       if result[0][0] != apiKey:
           return "ERROR - Authentication with the controller failed",400
       elif result[0][0] == apiKey:
           return func
   return funcWrapper

它装饰的路由相关功能:

@app.route('/unregister',methods=['POST'])
@requestAuth
def unregisterApi():
   data = request.get_json(force=True)
   apiKey = data["API Register Key"]
   apiAddr = request.remote_addr

   conn = sqlite3.connect('database/controllerConfiguration.db')
   cursor = conn.cursor()
   cursor.execute('delete from SystemAPI where apikey = \"{}\";'.format(apiKey))
   conn.commit()
   conn.close()

   return jsonify({"Response":"Success"})

我希望达到的目标是:

每次调用路由(/unregister,/register,...)装饰器时,@requestAuth装饰器都会检查是否传递了正确的Key,如果正确,它将恢复到route函数并执行应执行的操作,如果该键不匹配,它将简单地返回错误字符串以及相关的状态代码(string: "ERROR - Authentication with the controller failed", Status code: 400).

1 个答案:

答案 0 :(得分:1)

问题出在public OpenImage (byte[] bin) { InitializeComponent (); Image image = new Image { Source = ImageSource.FromStream(() => new MemoryStream(bin)) }; this.Content = image; } 中的elif语句中:

funcWrapper

elif result[0][0] == apiKey: return func 是一个可调用对象,即由func包装的原始函数,在这种情况下为requestAuth。而是调用unregisterApi返回有效类型,而不是对象实例本身:

func

此外,请记住,如果elif result[0][0] == apiKey: return func() if语句均失败,elif将返回None,从而再次引发原始错误。因此,您可能需要重新考虑如何处理该特定案例。