Created
June 5, 2021 22:19
-
-
Save coderanger/b7dc70144c0cab961f20925abd89aa69 to your computer and use it in GitHub Desktop.
DRF login view.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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