1

我正在使用 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 响应,就像现在一样
  • 公共用户发出 put/post/delete 调用:返回“未授权”响应
  • 注册用户发出 get/put/post/delete 调用:检查它是否已注册并回复适当的响应。

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

谢谢!

4

3 回答 3

2

这可以使用预处理器参数来完成create_api。例如:

# 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

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

# 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 测试。

于 2016-11-21T22:35:23.590 回答
0

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

于 2015-12-01T04:59:39.703 回答
0

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

于 2017-06-08T22:47:48.427 回答