Авторизация на основе токена приводит к неавторизованному 401 - PullRequest
0 голосов
/ 26 апреля 2020

Управление версиями пакета

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

Я работаю над проектом API, в котором для запроса POST к ресурсу Todo требуется, чтобы у пользователя был токен. При попытке проверить этот сценарий я получаю следующую ошибку утверждения: AssertionError: 401 != 201. И BasicHTTPAuth, и TokenHTTPAutth из flask -HTTPAuth обрабатывают учетные данные авторизации.

На основании того, что у пользователя есть токен для доступа к этому ресурсу, мне не ясно, почему я получаю 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}'}
        )
...