Преглед изворни кода

moved auth-checks to middleware
and add another subpage for demonstration

Rodja Trappe пре 1 година
родитељ
комит
6c12642078
1 измењених фајлова са 24 додато и 5 уклоњено
  1. 24 5
      examples/authentication/main.py

+ 24 - 5
examples/authentication/main.py

@@ -1,11 +1,15 @@
 #!/usr/bin/env python3
 #!/usr/bin/env python3
-"""This is just a very simple authentication example.
+"""This is just a simple authentication example.
 
 
 Please see the `OAuth2 example at FastAPI <https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/>`_  or
 Please see the `OAuth2 example at FastAPI <https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/>`_  or
 use the great `Authlib package <https://docs.authlib.org/en/v0.13/client/starlette.html#using-fastapi>`_ to implement a classing real authentication system.
 use the great `Authlib package <https://docs.authlib.org/en/v0.13/client/starlette.html#using-fastapi>`_ to implement a classing real authentication system.
 Here we just demonstrate the NiceGUI integration.
 Here we just demonstrate the NiceGUI integration.
 """
 """
+from urllib.parse import quote
+
+from fastapi import Request
 from fastapi.responses import RedirectResponse
 from fastapi.responses import RedirectResponse
+from starlette.middleware.base import BaseHTTPMiddleware
 
 
 from nicegui import app, ui
 from nicegui import app, ui
 
 
@@ -13,21 +17,36 @@ from nicegui import app, ui
 passwords = {'user1': 'pass1', 'user2': 'pass2'}
 passwords = {'user1': 'pass1', 'user2': 'pass2'}
 
 
 
 
+class AuthMiddleware(BaseHTTPMiddleware):
+    """This middleware redirects the user to the login page if they are not authenticated."""
+
+    async def dispatch(self, request: Request, call_next):
+        if request.url.path not in ['/login'] and not app.storage.user.get('authenticated', False):
+            return RedirectResponse(f'/login?referer_path={quote(request.url.path)}')
+        return await call_next(request)
+
+
+app.add_middleware(AuthMiddleware)
+
+
 @ui.page('/')
 @ui.page('/')
 def main_page() -> None:
 def main_page() -> None:
-    if not app.storage.user.get('authenticated', False):
-        return RedirectResponse('/login')
     with ui.column().classes('absolute-center items-center'):
     with ui.column().classes('absolute-center items-center'):
         ui.label(f'Hello {app.storage.user["username"]}!').classes('text-2xl')
         ui.label(f'Hello {app.storage.user["username"]}!').classes('text-2xl')
         ui.button(on_click=lambda: (app.storage.user.clear(), ui.open('/login')), icon='logout').props('outline round')
         ui.button(on_click=lambda: (app.storage.user.clear(), ui.open('/login')), icon='logout').props('outline round')
 
 
 
 
+@ui.page('/subpage')
+def test_page() -> None:
+    ui.label('This is a subpage page.')
+
+
 @ui.page('/login')
 @ui.page('/login')
-def login() -> None:
+def login(referer_path: str = '') -> None:
     def try_login() -> None:  # local function to avoid passing username and password as arguments
     def try_login() -> None:  # local function to avoid passing username and password as arguments
         if passwords.get(username.value) == password.value:
         if passwords.get(username.value) == password.value:
             app.storage.user.update({'username': username.value, 'authenticated': True})
             app.storage.user.update({'username': username.value, 'authenticated': True})
-            ui.open('/')
+            ui.open(referer_path or '/')
         else:
         else:
             ui.notify('Wrong username or password', color='negative')
             ui.notify('Wrong username or password', color='negative')