I made API Server with Python Flask-RESTful.
My system use token authentication for verify permission.
So, I added middleware for verify token.
For example, code like this,
[middleware.py]
class Test(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
print("gogo")
return self.app(environ, start_response)
[app.py]
from flask import Flask
from flask_restful import Api
from api.board import Article
from api.auth import Login, Register, RefreshToken
from middleware import Test
app = Flask(__name__)
api = Api(app)
api.add_resource(Login, '/login')
api.add_resource(Register, '/register')
api.add_resource(RefreshToken, '/refresh')
# middleware here
app.wsgi_app = Test(app.wsgi_app)
api.add_resource(Article, '/article')
if __name__ == '__main__':
app.run(debug=True)
I insert app.wsgi_app = Test(app.wsgi_app)
before /article
.
So I expect that only access to /article
will print "gogo", however every route print "gogo".
Maybe every route pass through with middleware.
How can I apply middleware for specific route? (In this code, only /article
)
Middlewares are created in Flask by creating a decorator; a function can have multiple middlewares, and the order matters a lot. You need to add a secret key to your application; this is what you should pass to JWT. Add the following to your app.py file below the app declaration.
One simple way this can be restricted is to check type of the user in createUser function and allow only if user is admin. But in general what is the best way to protect flask end points and give only few users the access to end points?
In order to demonstrate the use of POST method in URL routing, first let us create an HTML form and use the POST method to send form data to a URL. Now enter the following script in Python shell. After the development server starts running, open login. html in the browser, enter name in the text field and click Submit.
The decorator syntax is just a little syntactic sugar. This code block shows an example using our custom decorator and the @login_required decorator from the Flask-Login extension. We can use multiple decorators by stacking them.
There are a few ways how to add custom processing before specific endpoint.
1) Using python decorator:
from functools import wraps
def home_decorator():
def _home_decorator(f):
@wraps(f)
def __home_decorator(*args, **kwargs):
# just do here everything what you need
print('before home')
result = f(*args, **kwargs)
print('home result: %s' % result)
print('after home')
return result
return __home_decorator
return _home_decorator
@app.route('/home')
@home_decorator()
def home():
return 'Hello'
2) Using before_request
@app.before_request
def hook():
# request - flask.request
print('endpoint: %s, url: %s, path: %s' % (
request.endpoint,
request.url,
request.path))
# just do here everything what you need...
3) Using middleware. Just add condition on request path.
class Middleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
# not Flask request - from werkzeug.wrappers import Request
request = Request(environ)
print('path: %s, url: %s' % (request.path, request.url))
# just do here everything what you need
return self.app(environ, start_response)
@app.route('/home')
def home():
return 'Hello'
app.wsgi_app = Middleware(app.wsgi_app)
4) Also you can use before_request_funcs
to set list of functions before specific blueprint.
api = Blueprint('my_blueprint', __name__)
def before_my_blueprint():
print(111)
@api.route('/test')
def test():
return 'hi'
app.before_request_funcs = {
# blueprint name: [list_of_functions]
'my_blueprint': [before_my_blueprint]
}
app.register_blueprint(api)
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With