小能豆

是否可以在中间件类内进行重定向?

py

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


    def __call__(self, environ, start_response):
        request = Request(environ)
        cookies = request.cookies
        path = request.path


        if not isAuthenticated(cookies):
            #Redirect to /login

        return self.app(environ, start_response)

所以我有一个Middleware类,它应该从中获取cookiesrequest然后将其发送给一个isAuthenticated返回的函数True,或者False现在如果函数返回,False我需要重定向到/login页面,这可能吗?即使我没有request对象,我只有environ


阅读 9

收藏
2025-01-12

共1个答案

小能豆

是的,即使你只有 environ 而没有直接的 request 对象,你也可以通过修改 WSGI 中的 start_response 和返回适当的响应体来实现重定向功能。

以下是一个实现方法:

  1. 检查用户认证状态:根据 cookiesrequest.path,调用 isAuthenticated() 方法判断用户是否认证。
  2. 未认证时重定向:当 isAuthenticated() 返回 False 时,设置 HTTP 状态码为 302 并提供 Location 标头,将用户重定向到 /login

修改后的代码如下:

from werkzeug.wrappers import Request, Response

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

    def __call__(self, environ, start_response):
        # Create a request object using the WSGI environ
        request = Request(environ)
        cookies = request.cookies
        path = request.path

        # Check authentication
        if not isAuthenticated(cookies):
            # Redirect to /login
            response = Response("Redirecting to /login...", status=302)
            response.headers['Location'] = '/login'
            return response(environ, start_response)

        # If authenticated, continue with the original app
        return self.app(environ, start_response)

# Example function to simulate user authentication check
def isAuthenticated(cookies):
    # Example check: Look for a specific cookie
    return cookies.get("session_id") == "valid_session"

关键部分解释:

  1. 创建重定向响应
  2. 使用 werkzeug.wrappers.Response 创建一个 HTTP 响应对象。
  3. 设置状态码为 302(临时重定向)。
  4. 使用 response.headers['Location'] = '/login' 指定重定向目标。

  5. 调用 Response(environ, start_response)

  6. Response 对象支持直接将 WSGI 环境 environstart_response 传递给它,以便返回正确的 HTTP 响应。

  7. 继续传递请求

  8. 如果用户已认证(isAuthenticated() 返回 True),则调用 self.app(environ, start_response) 将请求传递到下一个 WSGI 应用程序。

依赖库

  • 上面的实现使用了 werkzeug.wrappers.Requestwerkzeug.wrappers.Response
  • 如果你没有安装 Werkzeug,可以通过以下命令安装:
    bash pip install werkzeug

测试方法

  1. 创建一个简单的 WSGI 应用程序:
    python def app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b"Hello, authenticated user!"]

  2. 包裹应用程序:
    python app_with_middleware = Middleware(app)

  3. 使用 WSGI 服务器运行,例如 wsgiref
    ```python
    from wsgiref.simple_server import make_server

if name == ‘main’:
server = make_server(‘localhost’, 8080, app_with_middleware)
print(“Serving on http://localhost:8080")
server.serve_forever()
```

访问 http://localhost:8080,未认证用户将被重定向到 /login 页面,而已认证用户将看到 Hello, authenticated user! 的响应。

2025-01-12