-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2904605
Showing
52 changed files
with
19,700 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Moti Kumar Yadav | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Django with React Authentication | ||
|
||
This project demonstrates a simple implementation of user authentication using Django on the backend and React on the frontend. It utilizes the SimpleJWT library for token-based authentication. | ||
|
||
## Features | ||
|
||
- User registration and login | ||
- Token-based authentication using SimpleJWT | ||
- Protected routes for authenticated users | ||
- Logout functionality | ||
|
||
## Technologies Used | ||
|
||
- Django | ||
- Django Rest Framework | ||
- SimpleJWT | ||
- React | ||
- React Router | ||
- Axios | ||
|
||
## Installation | ||
|
||
### Backend (Django) | ||
|
||
1. Clone the repository: | ||
|
||
```bash | ||
git clone https://github.com/moti9/Django-React-Authentication.git | ||
cd Django-React-Authentication | ||
``` | ||
2. Set up a virtual environment and install dependencies: | ||
```bash | ||
cd backend | ||
python -m venv venv | ||
source venv/bin/activate # On Windows: venv\Scripts\activate | ||
pip install -r requirements.txt | ||
``` | ||
3. Run migrations: | ||
```bash | ||
python manage.py migrate | ||
``` | ||
|
||
4. Start the Django development server: | ||
```bash | ||
python manage.py runserver | ||
``` | ||
|
||
|
||
# Frontend (React) | ||
1. In a new terminal window, navigate to the project root: | ||
```bash | ||
cd Django-React-Authentication | ||
``` | ||
|
||
2. Install frontend dependencies: | ||
```bash | ||
cd frontend | ||
npm install | ||
``` | ||
|
||
3. Start the React development server: | ||
```bash | ||
npm start | ||
``` | ||
|
||
# Usage | ||
1. Open your browser and go to http://localhost:8000 to access the React app. | ||
2. Register a new account or log in with existing credentials. | ||
3. Explore the protected routes available to authenticated users. | ||
4. Log out when done. | ||
|
||
# Contributing | ||
If you'd like to contribute to this project or want to make it more efficient, please follow these steps: | ||
|
||
1. Fork the repository. | ||
2. Create a new branch (git checkout -b feature/your-feature). | ||
3. Commit your changes (git commit -am 'Add new feature'). | ||
4. Push to the branch (git push origin feature/your-feature). | ||
5. Create a new pull request. | ||
|
||
# License | ||
This project is licensed under the MIT License - see the `LICENSE.md` file for details. | ||
|
||
|
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.contrib import admin | ||
|
||
# Register your models here. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class AccountsConfig(AppConfig): | ||
default_auto_field = 'django.db.models.BigAutoField' | ||
name = 'accounts' |
Empty file.
Binary file not shown.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.db import models | ||
|
||
# Create your models here. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from rest_framework import serializers | ||
from django.contrib.auth.models import User | ||
from django.contrib.auth import authenticate | ||
|
||
|
||
class UserSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = User | ||
fields = ["id", "first_name", "last_name", "username", "email"] | ||
extra_kwargs = {'password': {'write_only': True}} | ||
|
||
class SignupSerializer(serializers.ModelSerializer): | ||
first_name = serializers.CharField(required=True) | ||
last_name = serializers.CharField(required=True) | ||
email = serializers.EmailField(required=True) | ||
password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'}) | ||
|
||
class Meta: | ||
model = User | ||
fields = ["first_name", "last_name", "username", "email", "password"] | ||
|
||
def create(self, validated_data): | ||
user = User.objects.create_user(**validated_data) | ||
return user | ||
|
||
|
||
class LoginSerializer(serializers.Serializer): | ||
username = serializers.CharField(max_length=150, required=True) | ||
password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'}) | ||
|
||
def validate(self, data): | ||
username = data.get('username') | ||
password = data.get('password') | ||
|
||
user = authenticate(username=username, password=password) | ||
|
||
if user and user.is_active: | ||
data['user'] = user | ||
else: | ||
raise serializers.ValidationError('Unable to log in with provided credentials') | ||
|
||
return data | ||
|
||
# class LoginSerializer(serializers.Serializer): | ||
# username = serializers.CharField(max_length=150, required=True) | ||
# password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.test import TestCase | ||
|
||
# Create your tests here. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from django.urls import path | ||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView | ||
from . import views | ||
|
||
app_name = "accounts" | ||
|
||
urlpatterns = [ | ||
path("token/", TokenObtainPairView.as_view(), name="token_obtain_pair"), | ||
path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), | ||
path("token/verify/", TokenVerifyView.as_view(), name="token_verify"), | ||
path("signup/", views.SignupView.as_view(), name="signup"), | ||
path("login/", views.LoginView.as_view(), name="login"), | ||
path("logout/", views.LogoutView.as_view(), name="logout"), | ||
path("user/", views.UserProfile.as_view(), name="user"), | ||
] |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from rest_framework import status | ||
from django.contrib.auth.models import User | ||
from rest_framework.response import Response | ||
from rest_framework.views import APIView | ||
from rest_framework.permissions import AllowAny, IsAuthenticated | ||
from rest_framework.exceptions import AuthenticationFailed | ||
from rest_framework_simplejwt.tokens import RefreshToken | ||
from .serializers import SignupSerializer, LoginSerializer, UserSerializer | ||
from rest_framework_simplejwt.authentication import JWTAuthentication | ||
|
||
|
||
class UserProfile(APIView): | ||
permission_classes = (IsAuthenticated,) | ||
# authentication_classes = [JWTAuthentication] | ||
|
||
def get(self, request): | ||
user = User.objects.get(pk=request.user.id) | ||
serializer = UserSerializer(user) | ||
return Response(serializer.data, status=status.HTTP_200_OK) | ||
|
||
class SignupView(APIView): | ||
permission_classes = [AllowAny] | ||
|
||
def post(self, request, *args, **kwargs): | ||
serializer = self.get_serializer(data=request.data) | ||
|
||
if serializer.is_valid(): | ||
serializer.save() | ||
return Response(serializer.data, status=status.HTTP_201_CREATED) | ||
|
||
return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST) | ||
|
||
def get_serializer(self, *args, **kwargs): | ||
return SignupSerializer(*args, **kwargs) | ||
|
||
class LoginView(APIView): | ||
permission_classes = [AllowAny] | ||
|
||
def post(self, request, *args, **kwargs): | ||
serializer = self.get_serializer(data=request.data) | ||
serializer.is_valid(raise_exception=True) | ||
|
||
user = serializer.validated_data['user'] | ||
refresh, access = self.get_tokens_for_user(user) | ||
|
||
tokens = {'access': str(access), 'refresh': str(refresh)} | ||
return Response(tokens, status=status.HTTP_200_OK) | ||
|
||
def get_tokens_for_user(self, user): | ||
refresh = RefreshToken.for_user(user) | ||
access = refresh.access_token | ||
return refresh, access | ||
|
||
def get_serializer(self, *args, **kwargs): | ||
return LoginSerializer(*args, **kwargs) | ||
|
||
# class LoginView(APIView): | ||
# permission_classes = [AllowAny] | ||
# authentication_classes = [JWTAuthentication] | ||
|
||
# def post(self, request, *args, **kwargs): | ||
# serializer = self.get_serializer(data=request.data) | ||
# serializer.is_valid(raise_exception=True) | ||
|
||
# user = serializer.validated_data['user'] | ||
|
||
# refresh = RefreshToken.for_user(user) | ||
# tokens = {'access': str(refresh.access_token), 'refresh': str(refresh)} | ||
# return Response(tokens, status=status.HTTP_200_OK) | ||
|
||
# def get_serializer(self, *args, **kwargs): | ||
# return LoginSerializer(*args, **kwargs) | ||
|
||
class LogoutView(APIView): | ||
permission_classes = (IsAuthenticated,) | ||
authentication_classes = [JWTAuthentication] | ||
def post(self, request): | ||
try: | ||
refresh_token = request.data["refresh_token"] | ||
# print(refresh_token) | ||
token = RefreshToken(refresh_token) | ||
token.blacklist() | ||
return Response(status=status.HTTP_205_RESET_CONTENT) | ||
except Exception as e: | ||
return Response(status=status.HTTP_400_BAD_REQUEST) | ||
|
||
|
||
# class LogoutView(APIView): | ||
# permission_classes = [IsAuthenticated] | ||
# authentication_classes = [JWTAuthentication] | ||
|
||
# def post(self, request, *args, **kwargs): | ||
# try: | ||
# refresh_token = request.data.get('refresh_token', None) | ||
# if refresh_token: | ||
# token = RefreshToken(refresh_token) | ||
# token.blacklist() | ||
# return Response({"message": "Logout successful"}, status=status.HTTP_205_RESET_CONTENT) | ||
# except Exception as e: | ||
# return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) | ||
|
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
""" | ||
ASGI config for backend project. | ||
It exposes the ASGI callable as a module-level variable named ``application``. | ||
For more information on this file, see | ||
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ | ||
""" | ||
|
||
import os | ||
|
||
from django.core.asgi import get_asgi_application | ||
|
||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') | ||
|
||
application = get_asgi_application() |
Oops, something went wrong.