-1

I want to have middleware in my flask application to check for token, i do not want to use decorator, since there are hundreds of url routes.

middleware.py

from werkzeug.wrappers import Request, Response
import logging
import jwt
import traceback
from flask import request


class Middleware:
    """
    Middleware to check token
    """

    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        try:
            token = request.headers["HTTP_AUTHORIZATION"]
            token_json = jwt.decode(token, "secret_key", algorithms=['HS256'], audience='account')
            environ['USER_DETAIL'] = token_json
            return self.app(environ, start_response)

        except Exception as e:
            logging.info(traceback.print_exc())
            res = Response(u'{}'.format(e), mimetype='text/plain', status=401)
            return res(environ, start_response)

this throws and error on line token = request.headers["HTTP_AUTHORIZATION"]

Traceback (most recent call last):
  File "flask_service/middleware.py", line 20, in __call__
    token = request.headers["HTTP_AUTHORIZATION"]
  File "/usr/local/lib/python3.7/site-packages/werkzeug/local.py", line 348, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/usr/local/lib/python3.7/site-packages/werkzeug/local.py", line 307, in _get_current_object
    return self.__local()
  File "/usr/local/lib/python3.7/site-packages/flask/globals.py", line 37, in _lookup_req_object
    raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.

I tried environ["HTTP_AUTHORIZATION"] it gives key error since HTTP_AUTHORIZATION key is not present.

How do i check for token passed in request header in middleware. Please help me solve this.

Thanks in advance!

young_minds1
  • 1,181
  • 3
  • 10
  • 25

1 Answers1

0

The main reason is that Middlewares doesn't work with request context. You can combine not only Flask applications but any WSGI application. In this case you are running the same or different Flask applications that are entirely isolated from each other. They run different configurations and are dispatched on the WSGI level. But you can create request instance manually:

from flask import Request

class Middleware:
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        # you can't use from flask import request, but you can create request instance using environ:
        request = Request(environ)
        print(request.headers)
        return self.app(environ, start_response)

JFYI: not sure if you need middleware here. You can use other ways to process authorization token.

Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75