401 when trying to authenticate user in Eve flask framework

我怕爱的太早我们不能终老 提交于 2019-12-23 02:21:26

问题


I'm using the awesome Eve REST-framework for creating a CRUD API with JWT authentication. I've looked at the tutorials posted here but I'm receiving a 401 error when doing a POST request to my endpoints that require token auth.

I've read this SO question: Issue with the Python Eve TokenAuth Feature but I'm pretty sure the token is Base64 encoded.

This is the response I'm getting back from the server when doing a cURL GET request:

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}}

Below is my code:

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,
}

I have a token stored in my MongoDB for the user and I'm making the request with Postman and I'm including the token in the Authorization header like so:

Authorization: <USERTOKEN> 

Any thoughts on why this gives me a 401.

Thanks!


回答1:


I tested your code but, for simplicity, I got rid of jwt.encode:

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

I POSTed a new user to /users and then did a GET to the same endpoint with Postman: it works like a charm (200). Then I did the same test with curl:

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

That also retuns a 200. As you can see the Auth header is encoded (copy & paste from Postman request preview). Just make sure you are passing the right stuff, maybe set a breakpoint in check_auth to validate what's coming into it and wether the db lookup is successful or not.

Hope this helps in diagnosing your issue.

PS: please note that in curl the Authorization header also has a Basic statement before the token, which seems to be lacking in your code snippet.

UPDATE

For the sake of it I also installed PyJWT and tested your code and... it works just fine on my end. Must be something wrong with your request.

UPDATE2

One thing that might not be so obvious is that you still need to append an (encoded) : to your auth header (it's Basic Auth and it parses both username and pw). That's why in the above example you have a = at the end of the encoded 'hello'.



来源:https://stackoverflow.com/questions/27501022/401-when-trying-to-authenticate-user-in-eve-flask-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!