401在尝试在Eve瓶框架中验证用户时

时间:2014-12-16 09:11:00

标签: python authentication flask jwt eve

我使用了很棒的Eve REST-framework来创建一个带有JWT身份验证的CRUD API。我查看了教程posted here,但在对需要令牌身份验证的终端发出POST请求时,我收到了401错误。

我已经阅读了这个问题:Issue with the Python Eve TokenAuth Feature但我非常确定令牌是Base64编码的。

这是我在执行cURL GET请求时从服务器返回的响应:

curl -H "Authorization: <MYTOKEN>" -i http://MY_IP/users/548f6ecd64e6d12236c9576b

---- Response ----

HTTP/1.1 401 UNAUTHORIZED
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 16 Dec 2014 10:49:25 GMT
Content-Type: application/json
Content-Length: 91
Connection: keep-alive
WWW-Authenticate: Basic realm:"eve"

{"_status": "ERR", "_error": {"message": "Please provide proper credentials", "code": 401}}

以下是我的代码:

app.py

from eve import Eve
from eve.auth import TokenAuth

import jwt


class RolesAuth(TokenAuth):

    def check_auth(self, token, allowed_roles, resource, method):
        users = app.data.driver.db['users']
        # Add check of user credentials by decoding JWT
        user = users.find_one({'token': token})
        return user


def add_token(documents):
    for document in documents:
        payload = {'username': document['username']}
        document["token"] = jwt.encode(payload, 'secret')


if __name__ == '__main__':
    app = Eve(auth=RolesAuth)
    app.on_insert_users += add_token
    app.run()

settings.py

users_schema = {
    'username': {
        'type': 'string',
        'required': True,
    },
    'password': {
        'type': 'string',
        'required': True,
    },
    'email': {
        'type': 'string',
        'minlength': 1,
        'maxlength': 200,
        'required': True,
    },
    'token': {
        'type': 'string',
    },
    'created': {
        'type': 'datetime',
    }
}

users = {
    'cache_control': '',
    'cache_expires': 0,
    'extra_response_fields': ['token'],
    'public_methods': ['POST'],
    'schema': users_schema
}

DOMAIN = {
    'users': users,
}

我在MongoDB中为用户存储了一个令牌,并且我使用Postman发出请求,并且我在授权标头中包含令牌,如下所示:

Authorization: <USERTOKEN> 

为什么这会给我一个401的任何想法。

谢谢!

1 个答案:

答案 0 :(得分:0)

我测试了你的代码,但为了简单起见,我摆脱了jwt.encode

def add_token(documents):
    for document in documents:
        payload = {'username': document['username']}
        document["token"] = 'hello'

我将一个新用户发布到/users,然后使用Postman对同一个端点进行了GET:它就像一个魅力(200)。然后我用curl进行了相同的测试:

curl -H "Authorization: Basic Y2lhbzo=" -i http://localhost:5000/users

那也回归200。如您所见,Auth标头已编码(从Postman请求预览中复制和粘贴)。只要确保你传递正确的东西,可以在check_auth中设置一个断点来验证进入它的是什么,并且数据库查找是否成功。

希望这有助于诊断您的问题。

PS:请注意,在curl中,Authorization标头在令牌之前也有一个Basic语句,这似乎在您的代码段中缺失。

<强>更新

为了它,我还安装了PyJWT并测试了你的代码......它在我的结尾工作得很好。您的请求一定有问题。

<强> UPDATE2

可能不那么明显的一件事是你仍然需要将(编码的):附加到你的auth标头(它是Basic Auth并且它解析用户名和pw)。这就是为什么在上面的例子中你在编码'hello'的末尾有一个=