基于令牌的授权会导致未授权的401

时间:2020-04-26 06:34:14

标签: python flask flask-restful flask-httpauth

软件包版本

Flask          1.0.2
Flask-HTTPAuth 3.2.4
Flask-RESTful  0.3.8
itsdangerous   0.24

我正在研究一个API项目,其中对Todo资源的POST请求要求用户具有令牌。在尝试测试这种情况时,出现以下断言错误:AssertionError: 401 != 201。来自flask-HTTPAuth的BasicHTTPAuthTokenHTTPAutth都在处理授权凭据。

基于用户具有访问此资源的令牌的权限,我不清楚为什么会收到Unauthorized错误。 tests.py

class TestAuthenicatedUserPostTodo(ApiTestCase):
    '''Verify that an API user successfully adds a Todo'''

    def setUp(self):
        super().setUp()
        previous_todo_count = Todo.select().count()

        user = User.get(User.id == 1)
        token_serializer = Serializer(SECRET_KEY)
        self.token = token_serializer.dumps({'id': user.id})

    def test_todo_collection_post_todo_success(self):
        with app.test_client() as client:
            http_response = client.post(
                "/api/v1/todos/",
                headers={
                    'Authorization': f"Bearer {self.token}"
                },
                content_type="application/json",
                data={
                    "name": "Must do a todo",
                    "user": 1
                }
            )
        current_todo_count = Todo.select().count()

        self.assertEqual(http_response.status_code, 201)
        self.assertGreater(current_todo_count, previous_todo_count)

auth.py

basic_auth = HTTPBasicAuth()
token_auth = HTTPTokenAuth(scheme="Bearer")
auth = MultiAuth(token_auth, basic_auth)

@basic_auth.verify_password
def verify_password(username, password):
    try:
        api_user = User.get(User.username == username)
    except User.DoesNotExist:
        return False
    user_verified = api_user.check_password(password)
    if user_verified:
        g.user = api_user
        return True
    return False

@token_auth.verify_token
def verify_token(token):
    timed_serializer = Serializer(SECRET_KEY)
    try:
        user = timed_serializer.loads(token)
        api_user = User.get_by_id(user['id'])
    except (SignatureExpired, BadSignature) as e:
        abort(400, description=str(e))
    return True

todo.py


@auth.error_handler
def errorhandler():
    return jsonify(unauthorized="Cannot add Todo. Login required."), 401


class TodoCollection(Resource):

    @auth.login_required
    def post(self):
        import pdb; pdb.set_trace()
        args = self.request_parser.parse_args()
        if not args['name']:
            return make_response(
                {'invalid_request': "Invalid todo provided"}, 400
            )
        new_todo = Todo.create(**args)
        return (
            marshal(set_todo_creator(new_todo), todo_fields, 'new_todo'),
            201, {'Location': f'{new_todo.location}'}
        )

0 个答案:

没有答案