3

I am trying to integrate the Flask-RESTful's request parsing interface, reqparse in my backend to request HTTP headers from the client. Currently, I wish to use this for authentication of a user and wish to pass 'secret_key' in HTTP headers.

The function I am using for this task is the add_argument() function. My code for requesting the header is as follows:

reqparse = reqparse.RequestParser()
reqparse.add_argument('secret_key', type=str, location='headers', required=True)

However, on sending the following cURL request:

curl -H "Content-Type: application/json" -H "{secret_key: SECRET}" -X POST -d '{}' http://localhost:5000/authUser

I recieve the following 400 error on my Pycharm Community edition editor :

127.0.0.1 - - [02/Aug/2016 18:48:59] "POST /authUser HTTP/1.1" 400 -

and the following message on my cURL terminal:

{
  "message": {
    "secret_key": "Missing required parameter in the HTTP headers"
  }
}

To reproduce this error on Pycharm (and hopefully all other compilers as well), please use the files written below as follows:

Folder - Sample_App
    - __init__.py
    - run.py
    - views.py

__init__.py

from flask import Flask
from flask_restful import Api
from views import AuthUser

app = Flask(__name__)

api = Api(app)
api.add_resource(AuthUser, '/authUser')

views.py

from flask_restful import reqparse, Resource

class AuthUser(Resource):

    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('secret_key', type=str, location='headers', required=True)

    def post(self):
        data = self.reqparse.parse_args()
        if data['secret_key'] == "SECRET":
            print("Success")
            return 200
        return 400

run.py

from __init__ import app

app.run(host='0.0.0.0', port=5000, debug=True)

Could you please tell me how to fix this issue? I want to know if the location parameter needs to be changed or if there is something wrong in my cURL request.

EDIT:

With the help of Methika's response, I have figured out the error. The add_argument() function does not take _ in a headers parameter. However, when I use the requests.headers['secret_key'] function, I am able to request headers with the _ character just fine. Why is that the case?

New Code of views.py:

views.py

from flask_restful import reqparse, Resource

class AuthUser(Resource):

    def __init__(self):
        self.reqparse = reqparse.RequestParser()

    def post(self):
        data = self.reqparse.parse_args()
        data['secret_key'] = request.headers['secret_key']
        if data['secret_key'] == "SECRET":
            print("Success")
            return 200
        return 400
Vaibhav Bajaj
  • 1,934
  • 16
  • 29

2 Answers2

12

I did some tests with the code you gave here and I found out that the problem doesn't come from you code but from the name of the variable:

If you replace secret_key by secretkey (or something else without underscore) it will work !

I found this post, flask seems to not accept underscores in header variable names.

Community
  • 1
  • 1
Michael
  • 539
  • 6
  • 12
  • I beg to differ. If I make the same request using `request.headers['secret_key']`, it works just fine. Eg: in the post function, use `data['secret_key'] = request.headers['secret_key']`. It works but I wish to use this functionality. I will check out your solution though. – Vaibhav Bajaj Aug 05 '16 at 18:19
  • 1
    Your solution works, yet I do not like the reasoning as I am able to make the request using `request.headers['secret_key']`. Why is that? – Vaibhav Bajaj Aug 05 '16 at 18:23
  • 1
    No worries, I found the answer to my question here : https://github.com/kennethreitz/requests/issues/1292 – Vaibhav Bajaj Aug 05 '16 at 18:49
1

Instead of this curl request

curl -H "Content-Type: application/json" -H "{secret_key: SECRET}" -X POST -d '{}' http://localhost:5000/authUser

Try this one

curl -H "Content-Type: application/json" -H "secret_key: SECRET" -X     POST -d '{}' http://localhost:5000/authUser

In header normally I have seen using value like "Key: Value"

amey
  • 36
  • 1