From 882983fbd71a46239af98be82abc6062f0672bff Mon Sep 17 00:00:00 2001 From: xianfuxing Date: Sat, 14 Jul 2018 17:43:46 +0800 Subject: [PATCH] # finish user api login --- apps/accounts/api/serializers.py | 58 ++++++++++++++++++++++++++++++++ apps/accounts/api/urls.py | 8 +++++ apps/accounts/api/views.py | 22 ++++++++++++ mosqkiller/settings.py | 25 ++++++++++++++ mosqkiller/urls.py | 3 ++ 5 files changed, 116 insertions(+) create mode 100644 apps/accounts/api/serializers.py create mode 100644 apps/accounts/api/urls.py create mode 100644 apps/accounts/api/views.py diff --git a/apps/accounts/api/serializers.py b/apps/accounts/api/serializers.py new file mode 100644 index 0000000..c9ccbf2 --- /dev/null +++ b/apps/accounts/api/serializers.py @@ -0,0 +1,58 @@ +from rest_framework import serializers +from django.contrib.auth import get_user_model +from django.db.models import Q + +User = get_user_model() + + +class UserDetailSerializer(serializers.ModelSerializer): + + class Meta: + model = User + fields = ['username', 'email'] + + +class UserLoginSerializer(serializers.ModelSerializer): + token = serializers.CharField(allow_blank=True, read_only=True) + username = serializers.CharField(required=False, allow_blank=True) + email = serializers.EmailField(required=False, allow_blank=True) + + class Meta: + model = User + fields = [ + 'username', + 'email', + 'password', + 'token' + ] + + extra_kwargs = { + 'password': { + 'write_only': True + } + } + + def validate(self, data): + user_obj = None + username = data.get('username', None) + email = data.get('email', None) + password = data.get('password', None) + + if not email and not username: + raise serializers.ValidationError('username or email is required to login.') + user = User.objects.filter( + Q(username=username) | + Q(email=email) + ).distinct() + user = user.exclude(email__isnull=True).exclude(email__iexact='') + if user.exists() and user.count() == 1: + user_obj = user.first() + else: + raise serializers.ValidationError('This username/email is not valid.') + + if user_obj: + if not user_obj.check_password(password): + raise serializers.ValidationError('Incorrect credentials pls try again.') + data['token'] = 'SOME RANDOM TOKEN' + + return data diff --git a/apps/accounts/api/urls.py b/apps/accounts/api/urls.py new file mode 100644 index 0000000..a18e649 --- /dev/null +++ b/apps/accounts/api/urls.py @@ -0,0 +1,8 @@ +from django.urls import path +from .views import UserLoginAPIView + + +app_name = 'users-api' +urlpatterns = [ + path('login/', UserLoginAPIView.as_view(), name='login'), +] \ No newline at end of file diff --git a/apps/accounts/api/views.py b/apps/accounts/api/views.py new file mode 100644 index 0000000..c75df1c --- /dev/null +++ b/apps/accounts/api/views.py @@ -0,0 +1,22 @@ +from django.contrib.auth import get_user_model +from rest_framework.response import Response +from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST +from rest_framework.views import APIView +from rest_framework.permissions import AllowAny +from .serializers import UserLoginSerializer + +User = get_user_model() + + +class UserLoginAPIView(APIView): + permission_classes = [AllowAny] + serializer_class = UserLoginSerializer + + def post(self, request, *args, **kwargs): + data = request.data + serializer = UserLoginSerializer(data=data) + if serializer.is_valid(raise_exception=True): + login_data = serializer.data + return Response(login_data, HTTP_200_OK) + else: + return Response(serializer.errors, HTTP_400_BAD_REQUEST) diff --git a/mosqkiller/settings.py b/mosqkiller/settings.py index 2290334..4d5f17a 100644 --- a/mosqkiller/settings.py +++ b/mosqkiller/settings.py @@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/2.0/ref/settings/ import os import sys +import datetime # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -128,3 +129,27 @@ USE_TZ = True # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' + +# drf settings +REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.BrowsableAPIRenderer', + ), + # 'DEFAULT_PARSER_CLASSES': ( + # 'rest_framework.parsers.JSONParser', + # ), + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', + 'rest_framework.authentication.SessionAuthentication', + # 'rest_framework.authentication.BasicAuthentication' + ), + 'DEFAULT_PERMISSION_CLASSES': ( + # 'rest_framework.permissions.IsAuthenticatedOrReadOnly', + 'rest_framework.permissions.IsAuthenticated', + ) +} + +JWT_AUTH = { + 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=600), +} \ No newline at end of file diff --git a/mosqkiller/urls.py b/mosqkiller/urls.py index 7af8cd1..0a9822d 100644 --- a/mosqkiller/urls.py +++ b/mosqkiller/urls.py @@ -15,11 +15,14 @@ Including another URLconf """ from django.contrib import admin from django.urls import path, include +from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path('mosq_admin/', admin.site.urls), path('api/mosq/', include('mosquito.api.urls')), path('api/smart/', include('smart.api.urls')), + path('api/users/', include("accounts.api.urls")), + path('api/login/', obtain_jwt_token), ] urlpatterns += [