Django-Rest-Framework-Authentication

codepythonic
0

  

Django-Rest-Framework-Authentication



This project explains working of Django's Rest framework authentication system. We do API authentication using JWT tokens. We create a custom user class that modifies existing Django's base User class to login using email.



To implement authentication using Django Rest Framework, follow these step-by-step instructions:

  1. 1. Install the required packages:

    • asgiref==3.4.1
    • Django==3.2.5
    • django-cors-headers==3.7.0
    • djangorestframework==3.12.4
    • PyJWT==2.1.0
    • pytz==2021.1
    • sqlparse==0.4.1

    You can install these packages by running the command:



$ pip install asgiref==3.4.1
$ pip install Django==3.2.5
$ pip install django-cors-headers==3.7.0
$ pip install djangorestframework==3.12.4
$ pip install PyJWT==2.1.0
$ pip install pytz==2021.1
$ pip install sqlparse==0.4.1


    • OR


 pip install asgiref==3.4.1 Django==3.2.5 django-cors-headers==3.7.0 djangorestframework==3.12.4 PyJWT==2.1.0 pytz==2021.1 sqlparse==0.4.1



  1. 2 .Create a Django project named "authtutorial" by running the command:


  2. django-admin startproject authtutorial
Change directory to project config --

cd authtutorial

3.Let’s create an app now called the “users ”.
python manage.py startapp users 
4.Open the settings.py file inside the authtutorial project folder and add the following configurations:



INSTALLED_APPS = [
    ......,

    'rest_framework',
    'users',
    'corsheaders', #makes sure frontend connected with django
]


AUTH_USER_MODEL = 'users.User'
# override default User model


CORS_ORIGIN_ALLOW_ALL = True # FRONTEND PORT ACCESS
CORS_ALLOW_CREDENTIALS = True # fCOOKIES FOR FRONTEND




5.Open the models.py file inside the users app folder and define your user model or extend the Django built-in User model based on your requirements.

from django.db import models

# Create your models here.
#create User model
from django.contrib.auth.models import AbstractUser
# add your own profile fields and methods. AbstractBaseUser only contains the authentication functionality, but no actual fields
class User(AbstractUser):
    name = models.CharField(max_length=255)
    email = models.CharField(max_length=255, unique=True)
    password = models.CharField(max_length=255)
    username = None

    USERNAME_FIELD = 'email' # login w/ email, unique identifier.
    REQUIRED_FIELDS = []
    #has no effect in admin ui, it is list of the field names that will be prompted for when creating a user via the createsuperuser




6. Create a file named serializers.py inside the users app folder and next open the file define serializers.py for your user model.

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'name', 'email', 'password']

    # hide password
        extra_kwargs = {
            'password': {'write_only':True}
        }

    # hash passwords in the database, override default create function
    def create(self, validated_data):
        #extract password
        password = validated_data.pop('password', None)
        instance = self.Meta.model(**validated_data) #doesnt include password

        if password is not None:
            instance.set_password(password) #hashes password
        instance.save()
        return instance


7.Open the views.py file inside the users app folder and define the views for user registration, login, and other authentication-related functionality.

from django.shortcuts import render

from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import UserSerializer
from .models import User
from rest_framework.exceptions import AuthenticationFailed

import jwt
import datetime

# Create your views here.

class registerAPIView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)   #if anything not valid, raise exception
        serializer.save()
        return Response(serializer.data)


class LoginAPIView(APIView):
    def post(self, request):
        email = request.data['email']
        password = request.data['password']

        #find user using email
        user = User.objects.filter(email=email).first()

        if user is None:
            raise AuthenticationFailed('User not found:)')
           
        if not user.check_password(password):
            raise AuthenticationFailed('Invalid password')

       
        payload = {
            "id": user.id,
            "email": user.email,
            "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=60),
            "iat": datetime.datetime.utcnow()
        }

        token = jwt.encode(payload, 'secret', algorithm='HS256')
        # token.decode('utf-8')
        #we set token via cookies
       

        response = Response()

        response.set_cookie(key='jwt', value=token, httponly=True)  #httonly - frontend can't access cookie, only for backend

        response.data = {
            'jwt token': token
        }

        #if password correct
        return response


# get user using cookie
class UserView(APIView):
    def get(self, request):
        token = request.COOKIES.get('jwt')

        if not token:
            raise AuthenticationFailed("Unauthenticated!")
       
        try:
            payload = jwt.decode(token, 'secret', algorithms="HS256")
            #decode gets the user

        except jwt.ExpiredSignatureError:
            raise AuthenticationFailed("Unauthenticated!")
       
        user = User.objects.filter(id=payload['id']).first()
        serializer = UserSerializer(user)

        return Response(serializer.data)
        #cookies accessed if preserved

class LogoutView(APIView):
    def post(self, request):
        response = Response()
        response.delete_cookie('jwt')
        response.data = {
            'message': 'successful'
        }

        return response



8. Create a file named urls.py inside the users app folder and define the URL patterns for your app.

from django.urls import path, include
from .views import *

urlpatterns = [
    path('register/', registerAPIView.as_view()),
    path('login/', LoginAPIView.as_view()),
    path('user/', UserView.as_view()),
    path('logout/', LogoutView.as_view())
]

Finally, open the main urls.py file in the authtutorial project folder and include the URL patterns for the users app.
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('users.urls'))
]


  1. Run the following command to create the initial database migration:

    python manage.py makemigrations

    This command will analyze your models and create the necessary migration files



  2. Apply the migrations to the database by running the following command:

    python manage.py migrate
    1. Finally, start the Django development server by running the following command:

      python manage.py runserver

      The development server will start, and you can access your Django Rest Framework APIs at http://localhost:8000/api/.

    Make sure you have Python and Django properly installed before running these commands.


link below




Post a Comment

0Comments

Post a Comment (0)