Je dois fournir http-basic-auth
à une vue.Django: Authentique de base pour une vue (éviter middleware)
Je souhaite éviter de modifier les paramètres du middleware.
Fond: Ceci est une vue qui est remplie par une application distante.
Je dois fournir http-basic-auth
à une vue.Django: Authentique de base pour une vue (éviter middleware)
Je souhaite éviter de modifier les paramètres du middleware.
Fond: Ceci est une vue qui est remplie par une application distante.
Cette bibliothèque pourrait être utilisée: https://github.com/hirokiky/django-basicauth
utilitaires de base auth pour Django.
Les documents montrent comment l'utiliser:
Application décorateur CBV
Pour appliquer décorateur @basic_auth_requried à Vues Sur la base de la classe, utilisez django.utils.decorators.method_decorator.
Source: https://github.com/hirokiky/django-basicauth#applying-decorator-to-cbvs
Lorsque vous effectuez une demande d'authentification de base, vous ajoutez réellement des informations d'identification dans l'en-tête Authorization
. Avant le transit, ces informations d'identification sont codées en base64, vous devez donc les décoder à la réception.
L'extrait de code suivant suppose qu'il n'y a qu'un seul nom d'utilisateur et mot de passe:
import base64
def my_view(request):
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
token_type, _, credentials = auth_header.partition(' ')
expected = base64.b64encode(b'username:password').decode()
if token_type != 'Basic' or credentials != expected:
return HttpResponse(status=401)
# Your authenticated code here:
...
Si vous souhaitez comparer au nom d'utilisateur et mot de passe d'un modèle User
, essayez ce qui suit à la place:
def my_view(request):
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
token_type, _, credentials = auth_header.partition(' ')
username, password = base64.b64decode(credentials).split(':')
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
return HttpResponse(status=401)
password_valid = user.check_password(password)
if token_type != 'Basic' or not password_valid:
return HttpResponse(status=401)
# Your authenticated code here:
...
Veuillez noter que cette dernière version n'est pas extrêmement sécurisée. À première vue, je peux voir qu'il est vulnérable à timing attacks, par exemple.
Vous pouvez essayer un décorateur personnalisé (comme cela semble être la méthode recommandée here et here) au lieu d'ajouter de nouveaux middleware:
my_app/decorators.py
:
import base64
from django.http import HttpResponse
from django.contrib.auth import authenticate
from django.conf import settings
def basicauth(function):
def wrap(request, *args, **kwargs):
if 'HTTP_AUTHORIZATION' in request.META:
auth = request.META['HTTP_AUTHORIZATION'].split()
if len(auth) == 2:
if auth[0].lower() == "basic":
uname, passwd = base64.b64decode(auth[1]).split(':')
user = authenticate(username=uname, password=passwd)
if user is not None and user.is_active:
request.user = user
return view(request, *args, **kwargs)
response = HttpResponse()
response.status_code = 401
response['WWW-Authenticate'] = 'Basic realm="{}"'.format(
settings.BASIC_AUTH_REALM
)
return response
Ensuite, utilisez ceci pour décorer votre vue:
from my_app.decorators import basicauth
@basicauth
def my_view(request):
...
Oui, cela devrait fonctionner. Mais je pense que je suis sur la mauvaise voie si je le résous comme ça. J'ai des directives personnelles (pour moi). L'un est "Ne pas écrire le code source pour implémenter une sauvegarde" et le suivant "Ne pas écrire le code source pour implémenter l'authentification". Cela a été résolu par des gens plus talentueux auparavant et il y a déjà des implémentations qui ont été testées depuis plusieurs mois. Néanmoins merci pour cet extrait. Je pense que l'implémentation est beaucoup plus de code. – guettli