Files
François Voron 49deb437a6 Fix #42: multiple authentication backends (#47)
* Revamp authentication to allow multiple backends

* Make router generate a login route for each backend

* Apply black

* Remove unused imports

* Complete docstrings

* Update documentation

* WIP add cookie auth

* Complete cookie auth unit tests

* Add documentation for cookie auth

* Fix cookie backend default name

* Don't make cookie return a Response
2019-12-04 13:32:49 +01:00

54 lines
1.7 KiB
Python

from typing import Any, Optional
from fastapi.security import APIKeyCookie
from starlette.requests import Request
from starlette.responses import Response
from fastapi_users.authentication.jwt import JWTAuthentication
from fastapi_users.models import BaseUserDB
class CookieAuthentication(JWTAuthentication):
"""
Authentication backend using a cookie.
Internally, uses a JWT token to store the data.
:param secret: Secret used to encode the cookie.
:param lifetime_seconds: Lifetime duration of the cookie in seconds.
:param cookie_name: Name of the cookie.
:param name: Name of the backend. It will be used to name the login route.
"""
lifetime_seconds: int
cookie_name: str
def __init__(
self,
secret: str,
lifetime_seconds: int,
cookie_name: str = "fastapiusersauth",
name: str = "cookie",
):
super().__init__(secret, lifetime_seconds, name=name)
self.lifetime_seconds = lifetime_seconds
self.cookie_name = cookie_name
self.api_key_cookie = APIKeyCookie(name=self.cookie_name, auto_error=False)
async def get_login_response(self, user: BaseUserDB, response: Response) -> Any:
token = await self._generate_token(user)
response.set_cookie(
self.cookie_name,
token,
max_age=self.lifetime_seconds,
secure=True,
httponly=True,
)
# We shouldn't return directly the response
# so that FastAPI can terminate it properly
return None
async def _retrieve_token(self, request: Request) -> Optional[str]:
return await self.api_key_cookie.__call__(request)