Files
2020-01-11 10:55:02 +01:00

72 lines
2.4 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 cookie_path: Cookie path.
:param cookie_domain: Cookie domain.
:param cookie_secure: Whether to only send the cookie to the server via SSL request.
:param cookie_httponly: Whether to prevent access to the cookie via JavaScript.
:param name: Name of the backend. It will be used to name the login route.
"""
lifetime_seconds: int
cookie_name: str
cookie_path: str
cookie_domain: Optional[str]
cookie_secure: bool
cookie_httponly: bool
def __init__(
self,
secret: str,
lifetime_seconds: int,
cookie_name: str = "fastapiusersauth",
cookie_path: str = "/",
cookie_domain: str = None,
cookie_secure: bool = True,
cookie_httponly: bool = True,
name: str = "cookie",
):
super().__init__(secret, lifetime_seconds, name=name)
self.lifetime_seconds = lifetime_seconds
self.cookie_name = cookie_name
self.cookie_path = cookie_path
self.cookie_domain = cookie_domain
self.cookie_secure = cookie_secure
self.cookie_httponly = cookie_httponly
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,
path=self.cookie_path,
domain=self.cookie_domain,
secure=self.cookie_secure,
httponly=self.cookie_httponly,
)
# 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)