Aller au contenu

Authentification

Starlette fournit une interface simple mais puissante pour gérer l'authentification et les autorisations Une fois que vous avez installé AuthenticationMiddleware avec le backend d'authentification approprié, les interfaces request.user et request.auth seront disponibles dans votre terminal.

de starlette.applications import Starlette
de starlette. authentification import (
    AuthCredentiels, AuthenticationBackend, AuthenticationError, SimpleUser
)
de starlette.middleware import Middleware
de starlette.middleware. authentification import AuthenticationMiddleware
from starlette.responses import PlainTextResponse
de starlette.routing Route d'importation
Import base64
Import binascii


Classe BasicAuthBackend(Authentification Backend):
    async def authenticité (self, conn):
        Si "Authorization" n'est pas dans les têtes conn:
            Retour à

        auth = conn.headers["Authorization"]
        Essayez:
            scheme, credientials = auth.split()
            Si scheme.lower() != 'basic':
                Retour à
            decoded = base64.b64decode(credientials).decode("ascii")
        except (ValueError, UnicodeDecodeError, binascii.Error) comme exc:
            raise AuthenticationError('Invalid basic auth credientials')

        username, _, password = decoded.partition(":")
        # TODO: Vous voulez vérifier le nom d'utilisateur et le mot de passe ici.
        return AuthCredentials(["authentifié"]), SimpleUser(nom d'utilisateur)


async def homepage(demande):
    Si request.user.is_authentifié:
        return PlainTextResponse('Hello, ' + request.user.display_name)
    return PlainTextResponse ('Bonjour, ou')

routes = [
    Route("/", endpoint=homepage)
]

middleware = [
    Middleware(AuthenticationMiddleware, backend=BasicAuthBackend()))
]

app = Starlette(routes=routes, middleware=middleware)

Utilisateur

Une fois l'installation de AuthenticationMiddleware terminée, l'interface request.user sera disponible pour les terminaux ou autres middlewares.

Cette interface doit hériter de la sous-classe BaseUser qui fournit deux propriétés, ainsi que toute autre information contenue dans votre modèle utilisateur.

  • .is_authenticated
  • .display_name

Starlette propose deux implémentations utilisateur intégrées:UnauthenticatedUser() et SimpleUser(username).

Authentification des identifiants

Il est important que les informations d'identification d'authentification soient considérées comme un concept distinct de l'utilisateur Le schéma d'authentification devrait être capable de restreindre ou d'accorder des autorisations spécifiques indépendamment de l'identité de l'utilisateur.

La classe AuthCredentials fournit les interfaces de base exposées par request.auth:

  • .scopes

Autorité

Les autorisations sont implémentées comme des décorateurs de point de terminaison pour forcer les demandes entrantes à inclure la plage d'authentification requise.

depuis starlette. authentification import requires


@requires ('authentifié ')
async def dashboard(demande):
    ...

Vous pouvez inclure une ou plusieurs des plages souhaitées:

depuis starlette. authentification import requires


@requires(['authentifié', 'admin'])
async def dashboard(demande):
    ...

Par défaut, une réponse 403 est retournée lorsqu 'aucune autorisation n'est accordée. Dans certains cas, vous pouvez personnaliser cela, par exemple en masquant les informations sur la disposition de l'URL des utilisateurs non authentifiés.

depuis starlette. authentification import requires


@requires(['authentifié', 'admin'], status_code=404)
async def dashboard(demande):
    ...

!!! Remarque WebSockets ne prend pas en charge le paramètre status_code. pour ces cas, le code d'état 403 (interdit) sera toujours utilisé.

Ou vous voudrez peut-être rediriger les utilisateurs non authentifiés vers une autre page.

depuis starlette. authentification import requires


async def homepage(request):
    ...


@requires ('authentifié ', redirect =' homepage ')
async def dashboard(demande):
    ...

Lorsque vous redirigez les utilisateurs, la page vers laquelle vous les redirigez est affichée sur le site Web de votre site Web. next Les paramètres de la requête contiennent l'URL qu 'ils ont initialement demandée:

depuis starlette. authentification import requires
from starlette.responses import RedirectResponse


@requires ('authentifié ', redirect =' login ')
async def admin(demande):
    ...


async def login(demande):
    if request.method == "POST":
        #Maintenant que l'utilisateur est authentifié,
        #Nous pouvons les envoyer à leur destination originale demandée
        Si request.user.is_authentifié:
            next_url = request.query_params.get("next")
            Si next_url:
                return RedirectResponse(next_url)
            return RedirectResponse("/")

Pour les terminaux basés sur une classe, vous devez envelopper le décorateur autour des méthodes de la classe.

depuis starlette.authentication import requires
de starlette.endpoints import HTTPendpoint


Classe Dashboard(HTTPendpoint):
    @requires("authentifié")
    async def get(self, request):
        ...

Réponse d'erreur d'authentification personnalisée

Vous pouvez personnaliser la réponse d'erreur envoyée lorsque le backend d'authentification déclenche AuthenticationError:

de starlette.applications import Starlette
de starlette.middleware import Middleware
de starlette.middleware. authentification import AuthenticationMiddleware
de starlette.requests Demande d'importation
from starlette.responses import JSONResponse


def on_auth_Error(demande: demande, exc: Exception):
    return JSONResponse({"error": str(exc)}, status_code=401)

app = Starlette(
    middleware=[
        Middleware(AuthenticationMiddleware, backend=BasicAuthBackend(), on_Error=on_auth_Error),
    ],
)