Skip to content

Instantly share code, notes, and snippets.

@coderanger
Created June 5, 2021 22:19
Show Gist options
  • Save coderanger/b7dc70144c0cab961f20925abd89aa69 to your computer and use it in GitHub Desktop.
Save coderanger/b7dc70144c0cab961f20925abd89aa69 to your computer and use it in GitHub Desktop.
DRF login view.
from typing import Optional
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import AbstractBaseUser
from rest_framework.exceptions import ParseError
from rest_framework.permissions import AllowAny
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.throttling import ScopedRateThrottle
from rest_framework.views import APIView
from somewhere.serializers import UserSerializer
def _do_login(
request: Request,
user: AbstractBaseUser,
backend: Optional[str] = None,
*,
) -> Response:
"""Complete a login. Shared logic used by LoginView and PasswordResetConfirmView."""
login(request, user, backend=backend)
if request.query_params.get("mode") == "bearer":
# Bearer token return, so disable cookies on the response. The meta flag is used
# by CsrfViewMiddleware, by default login() requests the CSRF token be rotated
# but we don't want the middleware to set a cookie because CSRF isn't a thing
# with bearer tokens. So twiddle this internal flag. tests_login will catch if
# this breaks.
request.META["CSRF_COOKIE_USED"] = False
resp = Response({"token": request.session.session_key})
resp._token_session = True # type: ignore
return resp
else:
serializer = UserSerializer(user)
return Response(serializer.data)
class LoginView(APIView):
"""Login using any of the available backends."""
permission_classes = [AllowAny]
throttle_classes = [ScopedRateThrottle]
throttle_scope = "login"
def post(self, request: Request) -> Response:
user = authenticate(
request,
# INSERT authentication arguments here.
)
if user is None:
return Response({"error": "login failed"}, status=400)
return _do_login(request, user)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment