-
-
Save herotux/911a0d4744845d9f7e3d35e2a69b720d to your computer and use it in GitHub Desktop.
from django.contrib import admin | |
from .models import User | |
admin.site.register([User]) |
from django.db import models | |
from django.utils import timezone | |
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin | |
class UserManager(BaseUserManager): | |
def _create_user(self, email, password, is_staff, is_superuser, **extra_fields): | |
if not email: | |
raise ValueError('Users must have an email address') | |
now = timezone.now() | |
user = self.model( | |
email=self.normalize_email(email), | |
is_staff=is_staff, | |
is_active=True, | |
is_superuser=is_superuser, | |
last_login=now, | |
joined_at=now, | |
**extra_fields | |
) | |
user.set_password(password) | |
user.save(using=self._db) | |
return user | |
def get_by_natural_key(self, username): | |
return self.get(**{'{}__iexact'.format(self.model.USERNAME_FIELD): username}) | |
def create_user(self, email, password, **extra_fields): | |
return self._create_user(email, password, False, False, **extra_fields) | |
def create_superuser(self, email, password, **extra_fields): | |
return self._create_user(email, password, True, True, **extra_fields) | |
class User(AbstractBaseUser, PermissionsMixin): | |
email = models.EmailField('Email', max_length=255, unique=True) | |
name = models.CharField('Name', max_length=255, blank=True) | |
is_staff = models.BooleanField('Is staff', default=False) | |
is_active = models.BooleanField('Is active', default=True) | |
joined_at = models.DateTimeField('Joined at', default=timezone.now) | |
objects = UserManager() | |
USERNAME_FIELD = 'email' | |
REQUIRED_FIELDS = [] | |
# def __str__(self): | |
# return str(self.pk) | |
class Meta: | |
verbose_name = 'User' | |
verbose_name_plural = 'Users' | |
def get_full_name(self): | |
return self.name | |
def get_short_name(self): | |
return self.name |
from django.contrib.auth import authenticate | |
from rest_framework import serializers | |
from .models import User | |
from .validators import validate_username | |
class LoginSerializer(serializers.Serializer): | |
email = serializers.EmailField() | |
password = serializers.CharField() | |
def validate(self, attrs): | |
user = authenticate(username=attrs['email'], password=attrs['password']) | |
if not user: | |
raise serializers.ValidationError('Incorrect email or password.') | |
if not user.is_active: | |
raise serializers.ValidationError('User is disabled.') | |
return {'user': user} | |
class UserSerializer(serializers.ModelSerializer): | |
class Meta: | |
model = User | |
fields = ( | |
'id', | |
'last_login', | |
'email', | |
'name', | |
'is_active', | |
'joined_at', | |
'password' | |
) | |
read_only_fields = ('last_login', 'is_active', 'joined_at') | |
extra_kwargs = { | |
'password': {'required': True, 'write_only': True}, | |
'name': {'required': True} | |
} | |
@staticmethod | |
def validate_email(value): | |
return validate_username(value) | |
def create(self, validated_data): | |
return User.objects.create_user( | |
validated_data.pop('email'), | |
validated_data.pop('password'), | |
**validated_data | |
) |
from django.conf.urls import url | |
from rest_framework import routers | |
from . import views | |
urlpatterns = [ | |
url(r'^register/$', views.RegisterView.as_view(), name='user-register'), | |
url(r'^login/$', views.LoginView.as_view(), name='user-login'), | |
url(r'^logout/$', views.LogoutView.as_view(), name='user-logout'), | |
url(r'^current/$', views.UserView.as_view(), name='user-current'), | |
] |
from django.core.exceptions import ValidationError | |
from .models import User | |
def validate_username(username): | |
if User.objects.filter(**{'{}__iexact'.format(User.USERNAME_FIELD): username}).exists(): | |
raise ValidationError('User with this {} already exists'.format(User.USERNAME_FIELD)) | |
return username |
from django.conf import settings | |
from django.contrib.auth import login, logout | |
from rest_framework import views, generics, response, permissions, authentication | |
from .serializers import UserSerializer, LoginSerializer | |
class CsrfExemptSessionAuthentication(authentication.SessionAuthentication): | |
def enforce_csrf(self, request): | |
return | |
class LoginView(views.APIView): | |
permission_classes = (permissions.AllowAny,) | |
authentication_classes = (CsrfExemptSessionAuthentication,) | |
def post(self, request): | |
serializer = LoginSerializer(data=request.data) | |
serializer.is_valid(raise_exception=True) | |
user = serializer.validated_data['user'] | |
login(request, user) | |
return response.Response(UserSerializer(user).data) | |
class LogoutView(views.APIView): | |
def post(self, request): | |
logout(request) | |
return response.Response() | |
class RegisterView(generics.CreateAPIView): | |
serializer_class = UserSerializer | |
permission_classes = (permissions.AllowAny,) | |
def perform_create(self, serializer): | |
user = serializer.save() | |
user.backend = settings.AUTHENTICATION_BACKENDS[0] | |
login(self.request, user) | |
class UserView(generics.RetrieveAPIView): | |
serializer_class = UserSerializer | |
lookup_field = 'pk' | |
def get_object(self, *args, **kwargs): | |
return self.request.user |
How does this work with Javascript, where JS function dynamically calls a Django REST? Does it need to get the credentials (be they user/password, token) from a cookie?
How does this work with Javascript, where JS function dynamically calls a Django REST? Does it need to get the credentials (be they user/password, token) from a cookie?
Same question from me, it's possible to authenticate as session with the token in localstorage ?
@BATTLEROYALXS
Session authentication is used to avoid storing tokens in local storage as they are vulnerable to attacks.
The browser automatically send the session cookie to the server when it identifies the URL.
Your LoginView is not working for me.
This was helpful, thank you. I needed this line in my LogoutView
to get it working:
authentication_classes = (CsrfExemptSessionAuthentication,)
I also found this example helpful to complement this gist.
@Munsterberg You can always replace CsrfExemptSessionAuthentication with SessionAuthentication.
authentication_classes = (SessionAuthentication,)
This will include a csrf token with your response and set it in cookies