1

我正在使用令人敬畏的Eve REST 框架来创建具有 JWT 身份验证的 CRUD API。我查看了此处发布的教程,但在对需要令牌身份验证的端点执行 POST 请求时收到 401 错误。

我读过这个 SO 问题: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}}

下面是我的代码:

应用程序.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()

设置.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 标头中,如下所示:

Authorization: <USERTOKEN> 

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

谢谢!

4

1 回答 1

0

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

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

我向 Postman 发布了一个新用户/users,然后对同一个端点执行了 GET:它就像一个魅力 ( 200)。然后我做了同样的测试curl

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

这也将返回一个200. 如您所见,Auth 标头已编码(从 Postman 请求预览中复制和粘贴)。只要确保你传递了正确的东西,也许设置一个断点check_auth来验证其中的内容以及数据库查找是否成功。

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

PS:请注意,在 curl 中,Authorization 标头Basic在令牌之前还有一条语句,您的代码片段中似乎缺少该语句。

更新

为此,我还安装了 PyJWT 并测试了您的代码,并且......它对我来说工作得很好。你的要求一定有问题。

更新2

可能不太明显的一件事是,您仍然需要将(编码)附加:到您的身份验证标头(它是基本身份验证,它解析用户名和密码)。这就是为什么在上面的例子中你=在编码的“hello”的末尾有一个。

于 2014-12-16T16:43:16.890 回答