Python - ¿Cómo cerrar sesión en FastAPI-login?

CorePress2024-01-25  14

Tengo un sitio web básico en FastAPI. Me gustaría implementar un comportamiento de inicio de sesión/cierre de sesión (Auth) similar al inicio de sesión de Flask, es decir, permitir el acceso a una función/ruta con un decorador como @login_required o FastAPI Dependecy injection.

Encontré el módulo fastapi-login que anunciaba ser similar a Flask-login, pero tiene poca documentación, por decir lo menos. Falta por completo cerrar sesión

Entonces, estoy buscando ayuda para implementar correctamente el cierre de sesión.

Aquí está la estructura del archivo:

├── app
│   ├── __init__.py
│   └── main.py
├── requirements.txt
└── templates
    └── login.html.j2 

y código app.main.py funcionando sin cerrar sesión:

from fastapi.responses import RedirectResponse, HTMLResponse
from fastapi.security import OAuth2PasswordRequestForm
from fastapi_login import LoginManager 
from fastapi_login.exceptions import InvalidCredentialsException
from fastapi.templating import Jinja2Templates
from sys import path

app = FastAPI()

SECRET = "secret-key"

templates = Jinja2Templates(directory="templates")

manager = LoginManager(SECRET, tokenUrl="/auth/login", use_cookie=True)
manager.cookie_name = "some-name"

DB = {"username": {"password": "1234567"}}  # unhashed


@manager.user_loader
def load_user(username: str):
   user = DB.get(username)
   return user


@app.post("/auth/login")
def login(data: OAuth2PasswordRequestForm = Depends()):
   username = data.username
   password = data.password
   user = load_user(username)
   if not user:
       raise InvalidCredentialsException
   elif password != user['password']:
       raise InvalidCredentialsException
   access_token = manager.create_access_token(
       data={"sub": username}
   )
   resp = RedirectResponse(url="/private", status_code=status.HTTP_302_FOUND)
   manager.set_cookie(resp, access_token)
   return resp


@app.get("/private")
def getPrivateendpoint(_=Depends(manager)):
   return "You are an authentciated user"


@app.get("/public")
def getPublicendpoint():
   return "You are just a user"


@ app.get("/auth/login", response_class=HTMLResponse)
def login(request: Request):
   context = {'request': request, }
   return templates.TemplateResponse("login.html.j2", context)

He intentado cerrar sesión (a continuación), pero no funciona. simplemente redirige a la página de inicio de sesión, pero en realidad no elimina el acceso.

@ app.get("/auth/logout", response_class=HTMLResponse)
def logout(request: Request):
   response = RedirectResponse(url="/auth/login")
   response.delete_cookie("Authorization", domain="localtest.me")
   return response

Sospecho que hay algún problema con los parámetros delete_cookie, pero no tengo ni idea de quéEstos parámetros deberían ser:

response.delete_cookie("Authorization", domain="localtest.me") 

Aquí está la plantilla:

<link rel="stylesheet" href="https://unpkg.com/[email protected]/twinkle.min.css"/>
</head>
<body>
   <div class="flex p-4 m-6 justify-center">
       <form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" method="POST" action="/auth/login" >
         <div class="mb-4">
           <label class="block text-gray-700 text-sm font-bold mb-2" for="username">
             Username
           </label>
           <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="username" name="username" type="text">
         </div>
         <div class="mb-6">
           <label class="block text-gray-700 text-sm font-bold mb-2" for="password">
             Password
           </label>
           <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline" id="password" name="password" type="password">
         </div>
         <div class="flex items-center justify-between">
           <button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
             Sign In
           </button>
         </div>
       </form>
     </div>
</body>
</html>

Por favor ayuda con el cierre de sesión.



------------------------------------

Podrías hacer algo como esto:

@app.get("/logout")
def logout(response : Response):
  response = RedirectResponse('*your login page*', status_code= 302)
  response.delete_cookie(key ='*your access token name*')
  return response



------------------------------------

Tampoco he encontrado nada sobre esto. Pero entonces se me ocurrió la idea de sobrescribir la cookie con un token de acceso vacío.

@app.get('/logout', response_class=HTMLResponse)
def protected_route(request: Request, user=Depends(manager)):
    resp = RedirectResponse(url="/login", status_code=status.HTTP_302_FOUND)
    manager.set_cookie(resp, "")
    return resp
aRespondido el

4 de abril de 2021 a las 19:34

Nerón

Nerón

135

2

2 insignias de plata

8

8 insignias de bronce

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare