最简单的认证与烧瓶 - 不安

时间:2015-11-21 10:30:50

标签: python authentication flask python-requests flask-restless

我正在使用Flask-Restless来制作一个超级简单的REST API。我想添加身份验证,但仅用于put / post / delete调用,而我想将get调用公开。

到目前为止,我在views.py文件中输入了这个:

manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(models.mymodel, methods=['GET', 'POST', 'DELETE'])

我查看了不同的身份验证解决方案,但它们看起来都太“大”了。我只有一个应该能够进行PUT / POST / DELETE调用的用户,然后“公共”用户将只使用GET。

我认为一个简单的方法应该是这样的:

  • 进行get调用的公共用户:返回api响应,现在是
  • 进行看跌/发布/删除通话的公共用户:返回“未授权”回复
  • 注册用户进行get / put / post / delete调用:检查是否已注册并回复相应的响应。

“check”不应该像在我的config.py文件中存储一个秘密密钥,然后将它与api调用的标题的属性进行比较?我认为为用户创建一个完整的表,正如我在一些教程中看到的那样,然后生成API令牌的usernames+password太“大”而且在这里没有必要..因为我将是唯一的用户可以经过身份验证,我知道密钥是什么,我可以在标头中添加一些'secret-key' : mysecretkey。我错过了什么吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

这可以在create_api的{​​{3}}完成。例如:

# replace the next line with your favorite way or reading config files
access_password = 'mysecretkey'

def check_credentials(**kwargs):
    if flask.request.headers.get('X-Secret-Key','') != access_password:
        raise flask_restless.ProcessingException(code=401)  # Unauthorized

# create API
manager = flask_restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(models.mymodel, methods=['GET', 'POST', 'DELETE'],
                   collection_name='myobjects',
                   preprocessors={
                        'POST': [check_credentials],
                        'DELETE_SINGLE': [check_credentials],
                   })

使用Python 3.4,Flask 0.11.1,Flask-Restless 0.17.0进行测试。 Flask-Restless的旧版本可能需要DELETE而不是DELETE_SINGLE,以及不同的软件包名称。

如何使用cURL访问API的密码保护部分的示例:

curl -X POST -d '{"data":"my JSON data, etc."}' \
     -H "Content-Type: application/json" \
     -H "X-Secret-Key: mysecretkey" \
     http://localhost:5000/api/myobjects

这是一个简单的方案,但如果您的应用程序有可能在将来变得更大,我建议使用using preprocessors argument。数据库后端并不是必须大而复杂。这是您在极简主义实现中的起始案例(一个与硬编码密码一起使用):

# Anonymous object is sufficient here, a full-blown solution would define a class User
admin_user = type('', (object,), {"id": 1, "username": "admin", "password": "mysecret"})()

def authenticate(username, password):
    if username == admin_user.username and password == admin_user.password:
        return admin_user

def identity(payload):
    id = payload['identity']
    if id == admin_user.id:
        return admin_user


jwt = JWT(app, authenticate, identity)


@jwt_required()        
def check_credentials(**kwargs):
    pass

# create API as in the first example

使用Python 3.4,Flask 0.11.1,Flask-Restless 0.17.0,Flask-JWT 0.3.2进行测试。

答案 1 :(得分:0)

你可以试试flask-jwt,它很容易整合。它也有一个简单的例子。我也找到了一种方法来实现类似你的第3个要点,如果你有任何解决方案,请分享。

答案 2 :(得分:0)

当HTTP Basic Auth存在时,无需重新发送身份验证: