15👍
The /api-auth/login/
resource is only for authentication in the browseble api.
To use session authentication, you must create a session first.
You must have a login resource, which accepts user credentials and authenticates a user, using the Django authentication system.
On requesting that resource the client will get a cookie header.
The cookie and csrf token must be used in future requests.
curl -v -X POST https://example.com/api/user/login/ -d 'username=user&password=pass'
...
> Set-Cookie: csrftoken=TqIuhp8oEP9VY32tUDcfQyUwn3cqpYCa; expires=Fri, 15-May-2015 12:48:57 GMT; Max-Age=31449600; Path=/
> Set-Cookie: sessionid=4yb4s456lbvd974oijbdha7k3l6g52q3; expires=Fri, 30-May-2014 12:48:57 GMT; Max-Age=1209600; Path=/
DRF supports basic authentication too. You can use it to authenticate
user initially and create session. Here is an example:
from django.contrib.auth import login
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class MyBasicAuthentication(BasicAuthentication):
def authenticate(self, request):
user, _ = super(MyBasicAuthentication, self).authenticate(request)
login(request, user)
return user, _
class ExampleView(APIView):
authentication_classes = (SessionAuthentication, MyBasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth), # None
}
return Response(content)
1👍
For using in android it is better to use Token Authentication.
I’ve used Session Authentication in my Django sites that are Rectified.
Here the login api is called, which stored a session id.
You can call then any other APIs.
You need to enable Session Authentication in settings
settings.py
# Rest Framework
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}
Here’s the login api (function based view):
# accounts/views.py
import json
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from django.contrib.auth import authenticate, login
from django.http import JsonResponse
@api_view(['POST',])
@permission_classes((AllowAny,))
def login_view(request):
"""
POST API for login
"""
data = json.loads(request.body)
username = data.get('username')
password = data.get('password')
if username is None:
return JsonResponse({
"errors": {
"detail": "Please enter username"
}
}, status=400)
elif password is None:
return JsonResponse({
"errors": {
"detail": "Please enter password"
}
}, status=400)
# authentication user
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return JsonResponse({"success": "User has been logged in"})
return JsonResponse(
{"errors": "Invalid credentials"},
status=400,
)
here is the url.py file
# accounts/urls.py
from django.urls import include, path
from .api_views import login_view
urlpatterns = [
path('api-auth/login/', login_view, name="api-auth-login"),
]
- [Django]-How to fix VersionConflict locking failure in pipenv?
- [Django]-Generate unique id in django from a model field
- [Django]-Should django model object instances be passed to celery?
-2👍
If the intention is to access some endpoint by passing the username&password on the POST data, you can do the following:
urls.py
urlpatterns = [
url(r'^stuff/', views.MyView.as_view()),
...
]
views.py
from django.contrib.auth.models import User
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import exceptions
from rest_framework import authentication
from django.contrib.auth import authenticate, get_user_model
from rest_framework.authentication import BasicAuthentication,
SessionAuthentication
class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
# Get the username and password
username = request.data.get('username', None)
password = request.data.get('password', None)
if not username or not password:
raise exceptions.AuthenticationFailed(_('No credentials provided.'))
credentials = {
get_user_model().USERNAME_FIELD: username,
'password': password
}
user = authenticate(**credentials)
if user is None:
raise exceptions.AuthenticationFailed(_('Invalid username/password.'))
if not user.is_active:
raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
return (user, None) # authentication successful
class MyView(APIView):
authentication_classes = (SessionAuthentication, ExampleAuthentication,)
permission_classes = (IsAuthenticated,)
def post(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth), # None
}
return Response(content)
Curl
curl -v -X POST http://localhost:8000/stuff/ -d 'username=my_username&password=my_password'
- [Django]-Annotate a sum of two fields multiplied
- [Django]-Should my Django site's main page be an app?
- [Django]-How to write setup.py to include a Git repository as a dependency